首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型记录a= 'a‘不等于const a= 'a’as const和const a:'a'='a‘

类型记录a= 'a‘不等于const a= 'a’as const和const a:'a'='a‘
EN

Stack Overflow用户
提问于 2022-08-10 13:41:22
回答 2查看 79关注 0票数 2

好吧,TypeScript让我感到困惑的另一件事:

通常,我们可以跳过类型注释,因为我们知道TypeScript会为我们推断类型。

但是,无论是否使用类型注释,在某些情况下确实会产生真正的不同:

代码语言:javascript
复制
const a = 'a' // 'a'
//    ^?
const c = [a] // string[]
//    ^?

const a1 = 'a' as const // 'a'
//    ^?
const c1 = [a1] // 'a'[]
//    ^?

const a2:'a' = 'a' // 'a'
//    ^?
const c2 = [a2] // 'a'[]
//    ^?

游乐场

所以我现在知道它是怎么工作的了。

但是我的问题是:为什么c会被扩展到string[],它如何有用?

注意:这与数组或元组的工作方式无关,也与as const和type注释的工作方式无关。问题是为什么c不遵循c1c2,或者c1c2不遵循c,为什么不所有东西都是元组或者所有东西都是数组,为什么c必须是不同的?

c也扩展到string,这是不可取的,因为扩展意味着不安全,保持c扩展的意义是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-08-10 16:46:35

详细的工作原理主要是在微软/打字稿#10676中进行的。编译器通常会给出像"a"这样的字符串文本,但是根据上下文的不同,这些类型要么被认为是“拓宽”,要么被认为是文字类型。在某些情况下,拓宽文本类型将自动被加宽(因此"a"将变成string),而非拓宽类型将不会(因此"a"将保持"a")。

在以下方面:

代码语言:javascript
复制
const a = 'a' // 'a'
const c = [a] // string[]

a变量推断的类型是一个拓宽的文字类型"a",因为初始化器"a"发生在表达式中。因此,为[a]推断的类型是string[],因为a是一个加宽类型。

另一方面,

代码语言:javascript
复制
const a2:'a' = 'a' // 'a'
const c2 = [a2] // 'a'[]

a2推断的类型是一个非拓宽的文字类型"a",因为您将它作为注解,并且"a"发生在一个类型而不是表达式中。实际上,用文字类型注释变量是获得非拓宽类型而不是拓宽类型的推荐方法。

最后,在

代码语言:javascript
复制
const a1 = 'a' as const // 'a'
const c1 = [a1] // 'a'[]

a1的类型是非拓宽的"a"类型,因为断言总是导致非拓宽类型,如微软/打字稿#29510中所描述的那样。

所以这正好解释了为什么你看到的是你所看到的。

为什么有用的问题很难权威地回答,因为效用是主观的。您可以阅读microsoft/TypeScript#10676和微软/打字稿#11126以及与它们相关的问题,以获得更多的上下文。

通常的问题是,有时候人们希望像"a"这样的值被当作一个不变的值来对待,而另一些时候,人们希望它只是一个string。有个折中办法。除非人们明确地写出他们的意图,否则编译器必须推断出这个意图是什么,必须使用有时可能是错误的启发式方法。

如果我编写const a = "a",那么我知道它永远不会改变,所以不变和狭窄的"a"类型是合适的。将a视为string并不是错误的,但它会丢弃信息。

如果我编写let b = "b",那么我大概会更改这个值(否则我会使用const),所以string类型更合适。

如果我编写const c = [a],那么即使a"a"类型,也不清楚是否希望c永远只包含"a"类型的元素。那是..。奇怪,对吧?如果没有更多的上下文,很难想象为什么有人会想要一个字母"a"数组。string[]类型更常见,因此推断c是合理的,因为string[]是合理的。

如果您不择手段地告诉编译器a"a"类型,那么启发式方法将使用此方法。如果您有const a: "a" = "a",那么编译器现在就有一些迹象表明您真正关心该文字类型,而现在const c = [a]推断出"a"[]类型用于c。我仍然认为这是一种奇怪的类型(我认为您可以操纵数组中的"a"s的数量),但这正是推断给您的结果。如果我不喜欢这样,我可以写const c: string[] = [a]并澄清我的意图。

同样,这种行为是否有用也是一个意见问题。我只能给出我自己的意见(它非常有用,偶尔也会出错,此时我可以使用显式注释),并指出文档中的GitHub问题。

票数 4
EN

Stack Overflow用户

发布于 2022-08-10 16:45:47

这可以归结为大多数程序是如何由开发人员编写的,以及TypeScript团队如何努力适应他们所认为的意图。

最常见的情况是第一个例子:

代码语言:javascript
复制
const a = 'a' // 'a'
//    ^?
const c = [a] // string[]
//    ^?

// typically later:
c.push("some string content")

如果TS推断一个元组,或者一个文字值数组('a',而不是string类型),它就太严格了,许多常见的数组用法都会变成假正数(TS错误地违背了实际和合法的开发人员的意图)。

至于其他两个示例(c1和c2),TS团队决定推断一个文字值数组,因为开发人员确实给出了更大的提示,说明正在处理的文本值。

当然,这个假设可能是错误的,在这种情况下,开发人员需要显式地输入数组(例如Array<'a'|'b'>)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73307386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档