为什么我可以使用“as”,但不能在打字稿中为映射值分配类型?

Why can I use `as` but not assign the type for mapped values in typescript?

提问人:Lawrence_NT 提问时间:9/22/2023 最后编辑:Lawrence_NT 更新时间:9/22/2023 访问量:32

问:

我有一个对象列表,这些对象用 声明。as const

我还需要一个来自对象的相同值的列表,但不想维护两个列表。

所以我有这个......

export const patternTypes = [
    { title: 'Starts with', value: 'startsWith' },
    { title: 'Contains', value: 'contains' },
    { title: 'Regular Expression', value: 'regex' },
] as const;

const patternValues = patternTypes.map(item => item.value); // typed as string[]

由于我使用值列表(zod 枚举)的位置,我需要将类型转换为 .[string, ...string[]]

我想知道为什么我可以在映射之后将 type of 转换为 use,但我不能事先使用 声明变量的类型。patternValues[string, ...string[]]asconst patterns: [string, ...string[]]

我对类型声明的理解和类型声明是,它们实际上在做同样的事情。两者都需要与您要投射到的类型兼容,这就是为什么有些解决方案要绕过兼容性。asas any as <type I want>

有人可以向我解释一下吗...

为什么我能做到这一点

const patternValues = patternTypes.map(item => item.value) as [string, ...string[]];

但我不能这样做

const patternValues: [string, ...string[]] = patterns.map(item => item.value);
TypeScript 类型 转换

评论

0赞 sterling 9/22/2023
你只需要给出 map 函数的返回类型,默认设置为const patternValues: String[] = patterns.map<String>(item => item.value);any[]

答:

0赞 Nathan Wiles 9/22/2023 #1

他们没有做同样的事情。 更有力,并将覆盖编译器对类型的了解。它是一种强制转换,可用于坚持对象属于特定类型,即使其当前类型不同意。as

对于诸如 的类型声明,则不然,这些声明的值必须在编译时已知才能分配才能使用。const patterns: [string, ...string[]]

类型声明可能非常方便,通常非常安全,但更危险,应更加谨慎使用。as

评论

0赞 Behemoth 9/22/2023
类型断言不应称为强制转换。在 TypeScript 中,我们无法在运行时更改变量数据类型,这是您可以使用强制转换来执行的操作。您所要做的就是将变量断言为具有某种类型。
0赞 Lawrence_NT 9/23/2023
是的,这就是为什么它有点令人困惑。由于 和 实际上是同一类型。在 TS 中,选角不是一回事的目的地也是一个坚实的呼唤。这对我的心智模型有很大帮助!string[][string, ...string[]]
0赞 Nathan Wiles 9/25/2023
@Behemoth在TypeScript中运行时转换一个东西,我同意你的观点,区别很重要。事实上,我认为你的观点增加了更多的混乱,而不是它消除了。
1赞 Jay 9/22/2023 #2

类型断言

文档在这里

TypeScript 只允许转换为更具体或不太具体的类型版本的类型断言。此规则可防止“不可能”的胁迫,例如:enter image description here

const x = "hello" as number;

类型声明

为变量声明类型时,赋值时只能使用更具体的类型。

enter image description here

const x: string = "hello" as any as string | number

评论

0赞 Jay 9/22/2023
的类型是 ,所以它可以转换为 ,但不能分配给类型。patternTypes.map(item => item.value)("startsWith" | "contains" | "regex")[][string, ...string[]]as[string, ...string[]]