gpt4 book ai didi

typescript - Typeguard 不会缩小类型

转载 作者:行者123 更新时间:2023-12-02 16:27:35 24 4
gpt4 key购买 nike

我正在创建一个对象来存储一堆 RGB 颜色,并且允许嵌套。因此,在遍历对象时,我需要查看哪些键对应于 RGB 值或对象。但是,我尝试过的每种类型防护实际上都不会缩小类型范围。

type Color = [number, number, number] | 'transparent'
type ColorGroup = Record<string, Color>
type Colors = Record<string, Color | ColorGroup>

const colors: Colors = {
black: [0, 0, 0],
white: [255, 255, 255],
transparent: 'transparent',
primary: {
'50': [211, 233, 252],
'100': [179, 213, 248],
'200': [127, 185, 251],
'300': [68, 156, 253],
'400': [0, 126, 254],
'500': [13, 100, 226],
'600': [17, 79, 189],
'700': [15, 62, 157],
'800': [10, 46, 122],
'900': [1, 22, 77],
}
}

const isColor = (color: Color | ColorGroup): color is Color => {
return Array.isArray(color) || typeof color === 'string'
}

const usesColor = (color: Color):void => {
// does something with the color
}

for(const color in colors) {
if(isColor(colors[color])) usesColor(colors[color]) // error: type 'Record<string, Color>' is not assignable to type 'Color'
}

Playground link

有什么想法吗?我是否只是遗漏了一些关于类型保护的基本知识?

最佳答案

您遇到了 TypeScript 的设计限制。参见 microsoft/TypeScript#33391microsoft/TypeScript#31445获取更多信息。

问题是编译器不会跟踪属性类型保护的结果,除非这些属性是字符串文字或数字文字:

if (isColor(colors.black)) usesColor(colors.black); // okay

如果它是存储在变量中的值,则不是:

if (isColor(colors[color])) usesColor(colors[color]) // error!

当访问colors[color]时,编译器只知道color是一个string类型的变量。在类型保护之后,您再次访问 colors[color],但是编译器没有意识到您之前检查过它,因为 color 只是一些 string 类型的变量。在某种意义上,编译器看不出您的代码与此代码之间的区别:

declare const color1: string;
declare const color2: string;
if (isColor(colors[color1])) usesColor(colors[color2]); // error!

这不是类型保护的好用法。

上面的链接问题提到,如果支持这样的代码会很好,但事实证明它在编译器资源方面非常昂贵。跟踪哪些变量 用作索引是一项额外且几乎总是不必要的工作。这里的用例显然不值得……尤其是因为:


有一个小的重构可以提供您正在寻找的行为。不要进行多次索引操作,而是进行一次索引操作并将其保存到自己的变量中,如下所示:

for (const color in colors) {
const c = colors[color];
if (isColor(c)) usesColor(c) // okay
}

因为 c 是它自己的变量,所以不再需要担心使用 string 进行索引。编译器可以轻松地使用 c 上的类型保护来缩小 c 的类型。因此,您可以获得所需的行为,但代价是稍微不那么惯用的 JavaScript。

Playground link to code

关于typescript - Typeguard 不会缩小类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64190101/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com