打字稿如何使对象的打字成为其当前值的类型?

时间:2019-08-13 03:59:24

标签: typescript

const obj = { a: 1, b: '2' }

然后,obj的类型为:

{ a: number, b: string }

但是有时候,我希望它的类型是:

{ a: 1, b: '2' }

除了以下内容:

const obj: { a: 1, b: '2' } = { a: 1, b: '2' }

还有其他好方法吗?

2 个答案:

答案 0 :(得分:2)

如果要在推断常量类型时保留文字类型,则可以使用as const断言:


const obj = { a: 1, b: '2' } as const
// Same as
// const obj: {
//     readonly a: 1;
//     readonly b: "2";
// }

这也将使对象变为只读,但是对于常量来说还是可以的。

如果您不希望属性为readonly,则有几种选择,但是没有一个是无缝的。

一种选择是在文字上使用as const


const obj = { a: 1 as const, b: '2' as const } 
// Same as
// const obj: {
//     a: 1;
//     b: "2";
// }

或者先声明readonly版本,然后使其可变:


type Mutable<T> = { -readonly [P in keyof T]: T[P]}
const ro_obj = { a: 1 , b: '2' } as const
const obj: Mutable<typeof ro_obj> = ro_obj
// const obj: {
//     a: 1;
//     b: "2";
// }

或者我个人最喜欢的是使用函数来推断字符串文字类型:

function asLiterals<T extends Record<string, string | number | null | undefined | boolean >>(o: T) {
  return o;
}
const obj = asLiterals({ a: 1 , b: '2' });
// Same as 
// const obj: {
//     a: number;
//     b: string;
// }

答案 1 :(得分:1)

如果您要强制执行一个属性a的类型,该属性的值始终为1,或者更一般地说,强制执行某些属性的保证常数,请使其满足类似于以下内容的接口:

interface RedCircle extends Shape {
  type: "circle";
  color: "red";
}

请记住,这仅适用于属性中的原始值,包含其他文字值的对象或数组文字。如果仅以变量形式引用值,则可以在此处限制类型推断。 Typescript不能总是推断出命名事物的值。在这种情况下,这些类型签名主要充当断言,向下游代码保证应将值视为RedCircle