在我的应用程序中,我使用的值可以是静态值,也可以是返回这些值的函数。
对于typescript,我定义了静态值及其类型,如下所示
type Static = {
key1: number;
key2: string;
};
然后使用keyof Static
:
type DynamicValue<T> = () => T;
type Dynamic = {[key in keyof Static]: DynamicValue<Static[key]>};
在我的理解中,这应该和写这篇文章完全一样:
type DynamicValue<T> = () => T;
type Dynamic = {
key1: DynamicValue<number>;
key2: DynamicValue<string>;
};
(and实际上,在下面的代码中,这两种方法都会产生相同的错误)
现在我有了一个函数,它接受动态值并从中创建静态值,这就是问题所在:
function dynamicToStatic(d: Dynamic): Static {
const o: Static = {key1: 0, key2: ''};
for (const [key, callback] of Object.entries(d))
// the left-hand side of this assignment is marked with error:
// "Type 'string | number' is not assignable to type 'never'."
o[key as keyof Static] = callback();
return o;
}
(该函数还有一个变体,它应该将Partial<Dynamic>
作为参数,并返回Partial<Static>
,它显示了类似的错误:“类型”字符串|number'无法指派给型别' undefined '。”)
它似乎与Object.keys
无关,因为此版本具有相同的错误:
function dynamicToStatic(d: Dynamic): Static {
const o: Static = {key1: 1, key2: ''};
const keys = ['key1', 'key2'] as Array<keyof Static>;
for (const key of keys)
o[key] = d[key]();
return o;
}
我知道我可以通过将有问题的行替换为
(o as any)[key as keyof Static] = callback();
但很明显,typescript认为我做的事情有问题,但我就是不知道什么地方可能有问题。
那么,为什么我在上面的代码中看到这个错误呢?错误消息中的类型“undefined”/“never”到底是什么?为什么?
(full代码)
1条答案
按热度按时间k10s72fa1#
由于
o
可以包含string
或number
的值,因此在此赋值中callback
必须返回string & number
才能正常运行(因为为了安全起见,你必须同时满足string
和number
)。否则,你可能会把一个字符串赋给一个数字,反之亦然!然而,string & number
是不可能的,这就是为什么它被简化为never
(这就是never
的来源)。因为你不能把string | number
赋值给never
,所以你会得到一个错误。这个错误是 * 正确的 *,并且确实暗示了这个潜在的不安全赋值,但是我们知道它不是,因为键和回调应该有匹配的类型。有多种方法可以解决这个问题。
一种方法是强制转换为
never
,这看起来很奇怪,可能需要其他人花点时间来理解,但它确实有效,因为never
可以赋值给never
:我喜欢这个,因为它是最简单的......但您也可以使用
Object.defineProperty
(甚至Reflect.defineProperty
):最后,另一种方法是赋值的helper函数:
然后您可以将密钥转换为
keyof Static
: