TypeScript const 和 const 与 as const
Posted
技术标签:
【中文标题】TypeScript const 和 const 与 as const【英文标题】:TypeScript const and const with as const 【发布时间】:2021-07-24 04:31:15 【问题描述】:据我所知,TypeScript 将 const string
变量视为不可变类型变量,只有该值而没有其他可能的值。我一直认为在其中添加as const
是多余的。
为什么我在示例的第二部分得到以下内容?
“字符串”类型的参数不能分配给类型参数...
例子:
declare function each<T extends [any] | any[]>(cases: ReadonlyArray<T>): (name: string, fn: (...args: T) => any, timeout?: number) => void;
const foo1 = 'FOO' as const;
const bar1 = 'BAR' as const;
declare function action1(value: typeof foo1 | typeof bar1): void;
each([
[foo1],
])('test name', (value) =>
// okay
action1(value);
);
const foo2 = 'FOO';
const bar2 = 'BAR';
declare function action2(value: typeof foo2 | typeof bar2): void;
each([
[foo2],
])('test name', (value) =>
// Argument of type 'string' is not assignable to parameter of type '"FOO" | "BAR"'.(2345)
action2(value);
);
Playground sample above is here.
【问题讨论】:
【参考方案1】:即使您的问题的第一部分(使用 as const)没有警告任何错误,它仍然不起作用,因为 each
方法未编译为 javascript 代码,因此执行失败。
尽管您的示例试图解决 const 在缩小期间的行为问题,但我认为它太复杂了。您可能会发现以下关于 typescript 项目的建议问题很有用
Support Const Type Constraint
【讨论】:
【参考方案2】:TS 能够推断所有类型。你应该给一点爱)))
只需添加额外的泛型来帮助 TS 找出所有类型。 TS 足够聪明,即使没有as const
,也可以确定const foo='FOO'
是不变的。
declare function each<U extends string, V extends U[], T extends V>(cases: ReadonlyArray<T>): (name: string, fn: (...args: T) => any, timeout?: number) => void;
const foo1 = 'FOO' as const;
const bar1 = 'BAR' as const;
declare function action1(value: typeof foo1 | typeof bar1): void;
each([
[foo1],
])('test name', (value) =>
action1(value);
);
const foo2 = 'FOO';
const bar2 = 'BAR';
declare function action2(value: typeof foo2 | typeof bar2): void;
each([
[foo2],
])('test name', value => action2(value)); // ok
如您所见,我添加了额外的 U 和 V 泛型。
请记住,如果您无法推断出某种类型,请尝试添加更多泛型))这条规则在 80% 的时间里都有效)
Playground
为什么在示例的第二部分中出现“'string' 类型的参数不可分配给类型参数...”?
这是因为value
被推断为字符串。 action2
只需要 foo
或 bar
。因为string
类型比foo | bar
宽很多,TS报错
【讨论】:
【参考方案3】:不要将 const
作为声明不可变变量的关键字(顺便说一下,在 JS 中相同)与称为 const assertions 的 as const
混淆。
Const 断言的行为根据类型略有不同(请参阅文档的附加链接),但在文字类型的情况下,它基本上意味着它不能扩展(或扩大)到string
。它将它缩小到特定的文字类型,这向编译器发出不接受 string
的信号,这就是你得到的确切错误。
【讨论】:
以上是关于TypeScript const 和 const 与 as const的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 Typescript 中迭代 const 枚举?
在 TypeScript 中动态访问 const 对象字面量