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

2024-04-30

我刚刚读到新的constTypeScript 3.4 RC 中的断言功能,我没有看到它与使用有什么不同const声明。

我使用以下示例对此进行了测试公告页 https://devblogs.microsoft.com/typescript/announcing-typescript-3-4-rc这显然演示了如何使用as const (const断言)防止文字类型被扩大(例如,"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

然而,当我删除const断言并使用了const相反,编译器输出中没有任何变化or控制台输出并且没有抛出任何错误。

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

  return result;
}

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

&子弹;该表达式中的文字类型不应扩展(例如,不要从“hello”到字符串)
&子弹;对象字面量获取只读属性
&子弹;数组文字变成只读元组

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


本示例使用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;
  }
}

With --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;
             ~~~~~~

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

作为参考,这里是为返回类型推断的类型getShapes() with const宣言:

 ( { kind: string; radius: number; sideLength?: undefined; } 
  |{ kind: string; sideLength: number; radius?: undefined; } ) []

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

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

readonly [
   { readonly kind: "circle"; readonly radius: 100; }, 
   { readonly kind: "square"; readonly sideLength: 50; }
]

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TypeScript const 断言和声明有什么区别? 的相关文章

随机推荐