TypeScript const 断言和声明有什么区别?

Ada*_*dam 3 typescript typescript3.0

我刚刚读到了 TypeScript 3.4 RC 中的新const断言功能,但我没有看到它与使用声明有何不同const

我使用公告页面中的一个示例对此进行了测试,该示例显然演示了如何使用as constconst断言)防止文字类型被扩展(例如,"circle"to string)。

// Example from official announcement
function getShapes() {
  let result = [
    { kind: "circle", radius: 100 },
    { kind: "square", sideLength: 50 },
  ] as const;

  return result;
}

for (const shape of getShapes()) {
  if (shape.kind === "circle") {
    console.log("Circle radius", shape.radius);
  } else {
    console.log("Square side length", shape.sideLength);
  }
}

// Output:
// Circle radius 100
// Square side length 50
Run Code Online (Sandbox Code Playgroud)

但是,当我删除const断言并使用const声明代替时,编译器输出控制台输出没有任何变化,也没有抛出任何错误。

// Altered getShapes function
function getShapes() {
  const result = [
    { kind: "circle", radius: 100 },
    { kind: "square", sideLength: 50 },
  ];

  return result;
}
Run Code Online (Sandbox Code Playgroud)

那么有什么区别呢?公告页面列出了使用const断言的三个原因:

• 该表达式中的文字类型不应扩展(例如,不得从“hello”变为字符串)
• 对象文字获得只读属性
• 数组文字变为只读元组

但它没有解释断言和声明有何不同。

art*_*tem 5

此示例用于console.log测试推断类型。console.log不太关心它的参数类型,因此两种情况都没有错误。

如果测试需要更具体的类型,结果会有所不同:

// Altered getShapes function
function getShapes() {
  const result = [
    { kind: "circle", radius: 100 },
    { kind: "square", sideLength: 50 },
  ];

  return result;
}

for (const shape of getShapes()) {
  if (shape.kind === "circle") {
    const radius: number = shape.radius;
  } else {
    const length: number = shape.sideLength;
  }
}
Run Code Online (Sandbox Code Playgroud)

打开--strictNullChecks后,你会得到两个错误:

t.ts:25:11 - error TS2322: Type 'number | undefined' is not assignable to type 'number'.
  Type 'undefined' is not assignable to type 'number'.

25     const radius: number = shape.radius;
             ~~~~~~

t.ts:29:11 - error TS2322: Type 'number | undefined' is not assignable to type 'number'.
  Type 'undefined' is not assignable to type 'number'.

29     const length: number = shape.sideLength;
             ~~~~~~
Run Code Online (Sandbox Code Playgroud)

as const正如该功能所宣传的那样,当使用断言使编译器推断精确类型时,不会出现错误。

getShapes()作为参考,以下是为with声明的返回类型推断的类型const

 ( { kind: string; radius: number; sideLength?: undefined; } 
  |{ kind: string; sideLength: number; radius?: undefined; } ) []
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,kind被扩展为string,并且数组元素类型是一个包含声明了所有属性的元素的联合,只有其中一些在某些联合成员中是可选的 - 这就是为什么当您进行日志记录时,控制台日志中不会出现错误shape.radius-如果工会成员的类型错误,console.log将很乐意记录。undefined

getShapes()这是为with断言的返回类型推断的类型as const

readonly [
   { readonly kind: "circle"; readonly radius: 100; }, 
   { readonly kind: "square"; readonly sideLength: 50; }
]
Run Code Online (Sandbox Code Playgroud)

现在它是只读元组类型,而不是数组,并且每个元组成员都有精确的类型(并且kind是正确的文字类型,如预期的那样)。