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' }
还有其他好方法吗?
答案 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
。