打字稿中类型断言的详细逻辑是什么?
What is the detail logic of type assertion in typescript?
我将 type assertion
视为 Hi Compiler, I know the type of this variable better than you. Just follow me!
。
不过好像编译器还是有自己的推断类型的逻辑。例如,假设,
interface PM_MGEInfo {
category: string;
bid: string;
cid?: string;
labs?: { [key: string]: any };
}
那么1&2没问题,3就报TS2352错误
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}
};
}
为什么type assertion
开始检查3中的其他字段?有人知道它的详细逻辑吗?
更新:我在 Github Microsoft/TypeScript#23698 中创建了一个问题。
我看到两个选项。使用 Partial<T>
或 any
。使用任何一个时,您有责任确保一切正常,因此请作为最后一个选项使用。
两者的例子:
function makeMgeInfoWithPartial(bid: string): Partial<PM_MGEInfo> {
// props are optional but only those defined by PM_MGEInfo are valid
return {
bid,
labs: {a: 1}
}
}
function makeMgeInfoWithAny(bid: string): PM_MGEInfo {
return {
bid,
labs: {a: 1},
whatever: 'also works'
} as any
}
我认为编译器无法将您的值 {a: 1}
识别为 { [key: string]: any }
类型,因为如果您像这样更改行,则不会出现编译器错误:
function makeMgeInfo(bid: string): PM_MGEInfo {
return <PM_MGEInfo>{
bid,
labs: {a: 1} as {[key: string]: any}
};
}
如果您这样定义变量,它也可以工作:
mylabs: {[key: string]: any} = {a: 1};
并在您的函数中调用它:
makeMgeInfo(bid: string): PM_MGEInfo {
return <PM_MGEInfo>{
bid,
labs: this.mylabs
};
}
因此我想说,编译器无法识别您在实验室字段中定义的类型。这种情况下的错误消息非常具有误导性。
检查规范 4.16 Type Assertions, which is inspired by :
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.
对于情况 1,T
显然可以分配给 e
。
对于情况 2,e
的扩展形式是 {bid: string, labs: Object}
,T 可分配给它。注意labs?
是可以赋值给Object
的(其实我也不确定,但这是我唯一可能的解释)。
情况3,以上条件都不满足
我将 type assertion
视为 Hi Compiler, I know the type of this variable better than you. Just follow me!
。
不过好像编译器还是有自己的推断类型的逻辑。例如,假设,
interface PM_MGEInfo {
category: string;
bid: string;
cid?: string;
labs?: { [key: string]: any };
}
那么1&2没问题,3就报TS2352错误
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} }; }
为什么type assertion
开始检查3中的其他字段?有人知道它的详细逻辑吗?
更新:我在 Github Microsoft/TypeScript#23698 中创建了一个问题。
我看到两个选项。使用 Partial<T>
或 any
。使用任何一个时,您有责任确保一切正常,因此请作为最后一个选项使用。
两者的例子:
function makeMgeInfoWithPartial(bid: string): Partial<PM_MGEInfo> {
// props are optional but only those defined by PM_MGEInfo are valid
return {
bid,
labs: {a: 1}
}
}
function makeMgeInfoWithAny(bid: string): PM_MGEInfo {
return {
bid,
labs: {a: 1},
whatever: 'also works'
} as any
}
我认为编译器无法将您的值 {a: 1}
识别为 { [key: string]: any }
类型,因为如果您像这样更改行,则不会出现编译器错误:
function makeMgeInfo(bid: string): PM_MGEInfo {
return <PM_MGEInfo>{
bid,
labs: {a: 1} as {[key: string]: any}
};
}
如果您这样定义变量,它也可以工作:
mylabs: {[key: string]: any} = {a: 1};
并在您的函数中调用它:
makeMgeInfo(bid: string): PM_MGEInfo {
return <PM_MGEInfo>{
bid,
labs: this.mylabs
};
}
因此我想说,编译器无法识别您在实验室字段中定义的类型。这种情况下的错误消息非常具有误导性。
检查规范 4.16 Type Assertions, which is inspired by
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.
对于情况 1,T
显然可以分配给 e
。
对于情况 2,e
的扩展形式是 {bid: string, labs: Object}
,T 可分配给它。注意labs?
是可以赋值给Object
的(其实我也不确定,但这是我唯一可能的解释)。
情况3,以上条件都不满足