Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typescript中的as const #17

Open
vnues opened this issue Sep 13, 2021 · 0 comments
Open

typescript中的as const #17

vnues opened this issue Sep 13, 2021 · 0 comments

Comments

@vnues
Copy link
Owner

vnues commented Sep 13, 2021

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! <---注意这里

参考文献

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant