Skip to content

typescript中的as const #17

@vnues

Description

@vnues

const assertions

typescript3.4加入这个功能

const 断言顾名思义也是一种类型断言方式,不同于断言到具体的类型 'foo' as 'foo',它的写法是 'foo' as const 或者 { value: 'foo' } as const 。

它主要有以下特性:

  • string number boolean 字面量类型都不会被扩展;
  • 对象字面量的属性会变成只读的;
  • 数组字面量会变成只读的元组;
// Type '"hello"'
let x = "hello" as const;
// Type 'readonly [10, 20]'
let y = [10, 20] as const;
// Type '{ readonly text: "hello" }'
let z = { text: "hello" } as const;

image

除了tsx文件以外,也可以使用尖括号的断言语法。

// Type '"hello"'
let x = <const>"hello";
// Type 'readonly [10, 20]'
let y = <const>[10, 20];
// Type '{ readonly text: "hello" }'
let z = <const>{ text: "hello" };

基于 const assertions 的强大功能,推断出来的值都是确定的,我们不需要显式地声明更多定义来进行类型推断(比如省略readonly,也不需要给result注明类型,会自动推断):

image

// Works with no types referenced or declared.
// We only needed a single const assertion.
function getShapes() {
  let result = [
    { kind: "circle", radius: 100 },
    { kind: "square", sideLength: 50 }
  ] as const;

  return result;
}

for (const shape of getShapes()) {
  // Narrows perfectly!
 // 可以大胆使用,不用担心kind会变化
  if (shape.kind === "circle") {
    console.log("Circle radius", shape.radius);
  } else {
    console.log("Square side length", shape.sideLength);
  }
}

代替枚举类型

如果你选择不使用TypeScript的枚举类型,这甚至可以用来在普通的JavaScript代码中启用类似枚举的模式。

export const Colors = {
  red: "RED",
  blue: "BLUE",
  green: "GREEN",
} as const;
// or use an 'export default'
export default {
  red: "RED",
  blue: "BLUE",
  green: "GREEN",
} as const;

注意事项

有一点需要注意的是,const断言只能立即应用于简单的字面表达。

// Error! A 'const' assertion can only be applied to a
// to a string, number, boolean, array, or object literal.
let a = (Math.random() < 0.5 ? 0 : 1) as const;
let b = (60 * 60 * 1000) as const;
// Works!
let c = Math.random() < 0.5 ? (0 as const) : (1 as const);
let d = 3_600_000 as const;

const上下文并不能立即将表达式转换为完全不可变的。

let arr = [1, 2, 3, 4];
let foo = {
  name: "foo",
  contents: arr,
} as const;
foo.name = "bar"; // error!
foo.contents = []; // error!
foo.contents.push(5); // ...works! <---注意这里

参考文献

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions