Skip to content

Argument of type 'object & Record<"property", unknown>' is not assignable to parameter of type 'Interface'. #61619

Closed as not planned
@DonaldDuck313

Description

@DonaldDuck313

🔎 Search Terms

Argument of type 'object & Record<"property", unknown>' is not assignable to parameter of type 'Interface'.
Types of property 'property' are incompatible.
Type 'unknown' is not assignable to type 'number'.(2345)

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about TS2345 and unknown

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/JYOwLgpgTgZghgYwgAgJLmvJyDeAoZQ5ABygHtjowBPALmRAFcBbAI2gG48BfPPAEwgIANnCgoYjEAjDAyIZDAAUxMXGb10kWIggBKegDcywflwFDR45AnkBnMMjj0pAaxBkA7iC7BlNSjJlOD1kAF4I5AAiMlYAKyEwKOQAMhSnZABCSKZhYVT0qNIKKmpk0Ay05ACIIKU4ADpiyigaUIiw6KY2aCi9fCJFer0uXiA

💻 Code

interface Interface {
    property: number;
}

declare function f(param: Interface): void;

declare const a: unknown;
if(typeof(a) === "object" && a !== null && "property" in a && typeof(a.property) === "number"){
    f(a);
}

🙁 Actual behavior

I the following TS2345 error:

Argument of type 'object & Record<"property", unknown>' is not assignable to parameter of type 'Interface'.
  Types of property 'property' are incompatible.
    Type 'unknown' is not assignable to type 'number'.

🙂 Expected behavior

I shouldn't get any error. Inside the if block, nothing is of type unknown:

  • a itself is a non-null object because of typeof(a) === "object" && a !== null, so a itself is not of type unknown
  • a.property is a number because of "property" in a && typeof(a.property) === "number", so a.property is not of type unknown

So it makes no sense to get any error in the if block related to the type unknown.

While a may have other properties that are unknown, they're not referenced anywhere so that shouldn't matter.

Additional information about the issue

The following code which from a typing perspective does exactly the same thing works just fine:

interface Interface {
    property: number;
}

declare function f(param: Interface): void;

declare const a: unknown;
if(typeof(a) === "object" && a !== null && "property" in a && typeof(a.property) === "number"){
    const b: object = a;
    const c: number = a.property;
}

I don't see why this code should compile but not the other code.

Workarounds are to give a the type any instead of unknown or to use f(a as Interface), but both those workarounds defeat the purpose of what I'm trying to do since they would compile even if I made a mistake in the if condition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions