Home > database >  Function extends object with properties of type any vs unknown
Function extends object with properties of type any vs unknown

Time:12-03

In the below type definitions why do P1 and P2 have different values?

type P1 = (() => 22) extends {[k:string]:any} ? 1:2 //`P1 == 1`
type P2 = (() => 22) extends {[k:string]:unknown} ? 1:2 //`P2 == 2`

CodePudding user response:

In the first type definition, P1, the type of () => 22 is compared to an object with a string index and a value of any. Since a function can be converted to an object with a call property, the comparison returns true, and P1 is assigned the value of 1.

In the second type definition, P2, the type of () => 22 is compared to an object with a string index and a value of unknown. In this case, the comparison returns false, as a function cannot be directly converted to an object with a unknown value. That's why P2 is assigned the value of 2.

CodePudding user response:

See Breaking Change: { [k: string]: unknown } is no longer a wildcard assignment target for an authoritative answer.

The index signature {[k: string]: any} behaves specially in Typescript: it's a valid assignment target for any object type. Usually types like () => 22 are not given implicit index signatures, and so it is an error to assign () => 22 to {[k: string]: unknown}. Only when the property type is any do you get the special permissive behavior:

let anyRec: { [k: string]: any };
anyRec = () => 22; // okay

let unkRec: { [k: string]: unknown };
unkRec = () => 22; // error

So that's why P1 and P2 differ.

Playground link to code

  • Related