繁体   English   中英

Typescript 类型推断和文字类型

[英]Typescript type inference and literal types

为什么 Typescript 在第一个示例中推断类型string ,而它能够推断类型文字'good' | 'bad' 第二个例子中的'good' | 'bad'

const alwaysSomething = () => 'something' // inferred returned type: string
const moreComplicated = (mark: number) => mark >= 10 ? 'good' : 'bad' // inferred returned type:  'good' | 'bad'

操场上 如果你 hover alwaysSomething ,它显示它的类型是() => string ,但是如果你 hover moreComplicated ,它显示它的类型是(mark: number) => "good" | "bad" (mark: number) => "good" | "bad"

这个问题的规范答案(如果有的话)很可能在实现字面扩展算法的拉取请求中找到。 首先,我们可以看到您所看到的行为是预期的:

在没有返回类型注释的 function 中,如果推断的返回类型是文字类型(但不是文字联合类型)并且 function 没有包含文字类型的返回类型的上下文类型,则返回类型被扩大到其扩大的文字类型。

() => 'something'的推断返回类型是文字"something" ,然后扩展为string 另一方面,推断的返回类型为(mark: number) => mark >= 10? 'good': 'bad' (mark: number) => mark >= 10? 'good': 'bad'"good" | "bad" "good" | "bad" ,它是一种文字联合类型,因此不会被扩展。

为什么单值文字被加宽? 作者有这样的评论

[Y] 你几乎从不想要文字类型。 毕竟,为什么要写一个承诺总是返回相同值的 function 呢? 此外,如果我们推断一个字面量类型,这个常见的模式就会被打破:

 class Base { getFoo() { return 0; // Default result is 0 } } class Derived extends Base { getFoo() { // Compute and return a number } }

如果我们为Base.getFoo中的返回类型推断类型0 ,那么使用实际计算数字的实现来覆盖它将是错误的。 如果你真的想返回一个文字类型,你当然可以添加一个类型注释,即getFoo(): 0 { return 0; } getFoo(): 0 { return 0; }

为什么没有扩大字面联盟? 这是作者后来的评论

return cond? 0: 1 return cond? 0: 1推断的返回类型将为0 | 1 0 | 1 . 我认为在这种情况下,我们应该扩大到基本原始类型根本不清楚。 毕竟,返回类型为0 | 1 0 | 1实际上,从 function 中传递出有意义的信息。

所以问题是实用性之一:人们很少打算返回单个文字类型,但他们经常打算返回文字类型的联合。 由于类型推断总是可以被显式类型注释覆盖,因此您可以处理这种启发式给您错误的情况:

const alwaysSomething = (): 'something' => 'something' // inferred returned type: 
const moreComplicated = (mark: number): string => mark >= 10 ? 'good' : 'bad'

好的,希望有帮助。 祝你好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM