declare const action: { total: number } | { };
declare const defavlt: 200;
const total = (action.hasOwnProperty("total")) ? action.total : defavlt;
Run Code Online (Sandbox Code Playgroud)
导致以下 TS 错误action.total:
Property 'total' does not exist on type '{ type: "NEW_CONVERSATION_LIST" | "UPDATE_CONVERSATION_LIST_ADD_BOTTOM" | "UPDATE_CONVERSATION_LIST_ADD_TOP"; list: IDRArray<RestConversationMember>; total: number | undefined; } | ... 13 more ... | { ...; }'.
Property 'total' does not exist on type '{ type: "UPDATE_URL_STATE"; updateObj: IMessagingUrlState; }'.ts(2339)
Run Code Online (Sandbox Code Playgroud)
然而
const total = ("total" in action) ? action.total : defavlt
Run Code Online (Sandbox Code Playgroud)
作品。TS 以不同的方式对待这两种情况是否有理由?
jca*_*alz 12
在问题microsoft/TypeScript#10485 中,建议in操作符充当可用于过滤联合的类型保护;这是在microsoft/TypeScript#15256 中实现的, 并随 TypeScript 2.7一起发布。
这不是为了Object.prototype.hasOwnProperty(); 如果你真的对此有强烈的感觉,你可能想为它提交一个建议,注意到一个类似的建议 (microsoft/TypeScript#18282)被拒绝了,因为它要求对键进行更有争议的缩小而不是对象.. . 并且有些人同时想要(microsoft/TypeScript#20363)。并且不能保证该建议会被接受。
不过,对您来说幸运的是,您不必等待上游实现。与像 一样的运算符不同in,该hasProperty()方法只是一个库签名,可以对其进行更改以充当用户定义的类型保护函数。更重要的是,您甚至不必接触标准库定义;您可以使用声明合并来Object使用您自己的签名来扩充接口hasOwnProperty():
// declare global { // need this declaration if in a module
interface Object {
hasOwnProperty<K extends PropertyKey>(key: K): this is Record<K, unknown>;
}
// } // need this declaration if in a module
Run Code Online (Sandbox Code Playgroud)
此定义表示,当您检查 时obj.hasOwnProperty("someLiteralKey"),true结果意味着obj可分配给{someLiteralKey: unknown},而false结果则不能。这个定义可能并不完美,并且可能有很多边缘情况(例如,应该obj.hasOwnProperty(Math.random()<0.5?"foo":"bar")暗示什么?应该obj.hasOwnProperty("foo"+"bar")暗示什么?他们会做奇怪的事情)但它适用于您的示例:
const totalIn = ("total" in action) ? action.total : defavlt; // okay
const totalOwnProp = (action.hasOwnProperty("total")) ? action.total : defavlt; // okay
Run Code Online (Sandbox Code Playgroud)
好的,希望有帮助;祝你好运!
| 归档时间: |
|
| 查看次数: |
1846 次 |
| 最近记录: |