【发布时间】:2021-08-23 05:00:03
【问题描述】:
我可能在这里遗漏了一些明显的东西,但我已经坚持了一段时间。
鉴于以下谓词(我知道它技术上不是谓词):
const hasProp = <K extends PropertyKey, T extends {}> (obj: T, prop: K): obj is T & Record<K, unknown> => {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
我想做这样的事情:
const coreProps = ['id', 'module', 'name', 'auth'] as const;
for (const prop of coreProps) {
if (!hasProp(rawObject, prop)) {
throw new Error(`Missing property '${prop}'`);
}
}
但是,这不允许我使用例如rawObject.id 之后。 如果我手动展开循环,它会按预期工作。
是我做错了什么,还是 TypeScript 编译器的限制?
我确实想出了这个替代方案:
const hasProps = <Ks extends PropertyKey[], T extends {}> (obj: T, ...props: Ks): obj is T & { [K in Ks[number]]: unknown } => {
return props.every(prop => hasProp(obj, prop));
}
但我不喜欢这样,因为它不会返回任何关于缺少哪个属性的信息(如果有的话)。
【问题讨论】:
-
“但我不喜欢这个,因为它不会返回任何关于缺少哪个属性的信息......” 它不能像你的循环那样抛出吗?
-
技术上是的,但我在实用程序文件中有
hasProps,我几乎肯定会在其他地方使用它。理想情况下,我希望它与该实现细节隔离开来。 -
对我来说这似乎不是一个实现细节,它似乎是函数所固有的。但是你总是可以在错误的情况下使用一个伴随函数来告诉你缺少什么。无论如何,希望你能找到你喜欢的解决方案。
-
你说得对,这可能适合我的用例。我想现在我只是好奇为什么将循环从函数中取出会导致类型检查失败
标签: typescript