简体   繁体   English

Typescript 推断基于预期的 function 类型参数

[英]Typescript inference based on the expected function type parameters

type DateFormat = {
  year: "numeric";
}

function calculateDate (dateFormat: DateFormat) {
  /**
   * 
   */
}

const format = {
  year: "numeric"
}



calculateDate(format)

Sandbox 沙盒

Currently in Typescript 4.2, the inferred type definition for format is:目前在 Typescript 4.2 中, format的推断类型定义为:

{
    year: string;
}

This doesn't match the expected type alias, DateFormat , in the function call ( calculateDate ), because the year property of type string , isn't as specific as the string literal numeric .这与 function 调用 ( calculateDate ) 中的预期类型别名DateFormat不匹配,因为string类型的 year 属性不如字符串文字numeric那样具体。

If however, I passed the format object argument directly from the function call, TS seems to be able to infer the type in the context of the call - and correctly validate the type against DateFormat.但是,如果我直接从 function 调用中传递了format object 参数,则 TS 似乎能够在调用的上下文中推断类型 - 并根据 DateFormat 正确验证类型。

calculateDate({
  year: "numeric"
})

Therefore, I'm wondering whether this is a limitation in Typescript inference-algorithm ability, or an active design decision of the language?因此,我想知道这是 Typescript 推理算法能力的限制,还是语言的主动设计决策?

you must use a const assertion as const :您必须使用const 断言as const

const format = {
  year: "numeric"
} as const;

Quote from the docs:从文档中引用:

When we construct new literal expressions with const assertions, we can signal to the language that当我们用 const 断言构造新的文字表达式时,我们可以向语言发出信号:

  • no literal types in that expression should be widened (eg no going from "hello" to string)不应该扩大该表达式中的文字类型(例如,不要从“hello”变为字符串)
  • object literals get readonly properties array object 文字获取只读属性数组
  • literals become readonly tuples文字变成只读元组

Playground link 游乐场链接

To answer the question in the comment:要回答评论中的问题:
Yes, it is a design decision, because there are use-cases for the wide and for the tight type.是的,这是一个设计决策,因为有宽和紧类型的用例。

An example where we want to have the wide type is this:我们想要宽类型的一个例子是这样的:

function foo(opts = {
  color: 'blue'
}) {}

foo({
  color: 'green'
})

In this case, we want the color property to be of type string - not blue .在这种情况下,我们希望color属性是string类型,而不是blue

Playground example 2 游乐场示例 2

This algorithm called Excess Property Checks这种算法称为多余的属性检查

Object literals get special treatment and undergo excess property checking when assigning them to other variables, or passing them as arguments. Object 文字在将它们分配给其他变量或将它们作为 arguments 传递时得到特殊处理并进行过多的属性检查。 If an object literal has any properties that the “target type” doesn't have, you'll get an error:如果 object 文字具有“目标类型”没有的任何属性,您将收到错误消息:

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

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