我将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。
答案 0 :(得分:1)
检查规范4.16 Type Assertions,其灵感来自this answer:
在&lt;形式的类型断言表达式中。 T> e,e由T进行上下文类型化(第4.23节),并且所得到的e类型需要可分配给T,或者T需要可分配给结果类型e的扩展形式,否则编译时发生错误。
对于案例1,T
显然可以分配给e
。
对于案例2,e
的加宽形式为{bid: string, labs: Object}
,T可分配给。请注意,labs?
可分配给Object
(事实上,我不确定,但这是我唯一可能的解释)。
对于案例3,上述条件均不满足。
答案 1 :(得分:0)
我看到两个选项。使用Partial<T>
或any
。当使用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
}
答案 2 :(得分:0)
我认为编译器不会将您的值{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
};
}
因此我想说,编译器无法从labs字段识别您定义的类型。在这种情况下的错误消息是非常误导。