如果将键写入字符串文本,我可以使用TypScript的in
关键字以类型安全的方式判断对象是否具有键:
function guardHasTest <Data extends object> (
value: Data
): Data & Record<'test', unknown> {
if (!('test' in value)) {
throw new Error('Missing key')
},
return value
}
然而,如果我将键设为动态字符串,则相同的语法不会缩小类型范围:
function guardHasKey <Data extends object, Key extends string> (
value: Data,
key: Key
): Data & Record<Key, unknown> {
if (!(key in value)) {
throw new Error('Missing key')
}
return value
// Type 'Data' is not assignable to type 'Data & Record<Key, unknown>'.
Type 'object' is not assignable to type 'Data & Record<Key, unknown>'.
Type 'object' is not assignable to type 'Data'.
'object' is assignable to the constraint of type 'Data', but 'Data' could be instantiated with a different subtype of constraint 'object'.
Type 'Data' is not assignable to type 'Record<Key, unknown>'.
Type 'object' is not assignable to type 'Record<Key, unknown>'.ts(2322)
}
我不想使用自定义类型保护,因为它们的逻辑不是类型安全的:
export function isKeyOf<T, const Key extends string>(
obj: T,
key: Key
): obj is T & Record<Key, unknown> {
return true // No error, even though the logic is not correct
}
如何让函数以完全类型安全的方式动态判断对象是否具有键?