如何从 Typescript 中的常量定义字符串文字联合类型

How to define string literal union type from constants in Typescript

我知道我可以定义字符串联合类型以将变量限制为可能的字符串值之一:

type MyType = 'first' | 'second'
let myVar:MyType = 'first'

我需要从常量字符串构造一个类似的类型,例如:

const MY_CONSTANT = 'MY_CONSTANT'
const SOMETHING_ELSE = 'SOMETHING_ELSE'
type MyType = MY_CONSTANT | SOMETHING_ELSE

但由于某种原因它不起作用;它说 MY_CONSTANT refers to a value, but it being used as a type here.

为什么Typescript允许第一个例子,而不允许第二个例子?我正在使用 Typescript 3.4.5

要获取变量的类型,您需要使用 typeof 类型运算符:

const MY_CONSTANT = 'MY_CONSTANT' // must be const, no annotation. let or var will not work
const SOMETHING_ELSE = 'SOMETHING_ELSE' // must be const, no annotation. let or var will not work
type MyType = typeof MY_CONSTANT | typeof SOMETHING_ELSE

Playground

注:

因为人们在使用它时似乎有很多困惑。 const 很重要。如果您使用其他类型的声明(letvar),最终类型将是字符串。只有 const 保留字符串文字类型。

注二:

要使此解决方案起作用,您必须const上指定任何类型注释,并让编译器推断常量的类型(例如这将不工作 :const MY_CONSTANT: string = 'MY_CONSTANT')

您也可以在这种情况下使用枚举。例如:

// Define enum.
enum myConstants {
  MY_CONSTANT = 'my_constant',
  SMTH_ELSE = 'smth_else'
}

// Use it in an interface for typechecking.
interface MyInterface {
  myProp: myConstants
}

// Example of correct object - no errors.
let a: MyInterface = {
  myProp: myConstants.MY_CONSTANT
}

// Incorrect value - TS reports an error.
let b: MyInterface = {
  myProp: 'John Doe'
}

More about enums

枚举很好地涵盖了案例:

export enum ITEM_TYPES {
    TYPE1 = 'text',
    TYPE2 = 'image'
}

export type IItemType = ITEM_TYPES.TYPE1 | ITEM_TYPES.TYPE2

然后在代码中 ITEM_TYPES 可以参考各种运行时比较:

if (type === ITEM_TYPES.TYPE1){
}