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.