I treat type assertion
as something like Hi Compiler, I know the type of this variable better than you. Just follow me!
.
But it seems that the compiler still has its own logic to infer the type. For example, suppose,
interface PM_MGEInfo {
category: string;
bid: string;
cid?: string;
labs?: { [key: string]: any };
}
Then, 1&2 are no problem, but 3 throws a TS2352 error.
function makeMgeInfo(bid: string): PM_MGEInfo {
return <PM_MGEInfo>{
bid
};
}
function makeMgeInfo(bid: string): PM_MGEInfo {
return <PM_MGEInfo>{
bid,
labs: {}
};
}
function makeMgeInfo(bid: string): PM_MGEInfo {
return <PM_MGEInfo>{
bid,
// error TS2352: Type '{ labs: { poi_id: string; }; bid: string; }' cannot be converted to type 'PM_MGEInfo'.
// Property 'category' is missing in type '{ labs: { poi_id: string; }; bid: string; }'.
labs: {a: 1}
};
}
Why does type assertion
begin to check other fields in 3? Does someone know its detail logic?
Updated: I created an issue in Github Microsoft/TypeScript#23698.
Check the spec 4.16 Type Assertions, which is inspired by this answer:
In a type assertion expression of the form < T > e, e is contextually typed (section 4.23) by T and the resulting type of e is required to be assignable to T, or T is required to be assignable to the widened form of the resulting type of e, or otherwise a compile-time error occurs.
For case 1, T
is assignable to e
obviously.
For case 2, the widened form of e
is {bid: string, labs: Object}
, which T is assignable to. Notice that labs?
is assignable to Object
(In fact, I am not sure about it, but this is my only possible explanation).
For case 3, neither of above conditions is satisfied.