use*_*768 9 types constants literals typescript typesafe
我想将具有常量类型的两者结合起来,并使用它“作为常量”来获取文字类型作为类型:
type MyType = {name: string};
const x:MyType = {
name: 'test' // Autocompleted, typesafe. But Type is {name: string}, not
// what I want, {name: 'test'}
}
const x = { name: 'test' } as const; // Gives correct type, but no type check...
Run Code Online (Sandbox Code Playgroud)
这该怎么做?
Tom*_*rez 52
在 Typescript 4.9 中,我们现在可以使用satisfies运算符:
type MyType = { name: string }
const x ={
name: 'test', // Autocompleted, typesafe
} as const satisfies MyType
x.name // type is 'test' (not string)
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因,您无法使用satisfies,则复制相同的行为相当容易:
/**
* Replacement for TS satisfies operator, until it's well supported
* Usage:
* const test = satisfy<{ a: string }>()({ a: 'test', b: 'test' })
* */
export function satisfy<TSatisfied>(): <T extends TSatisfied>(value: T) => T {
return (value) => value
}
Run Code Online (Sandbox Code Playgroud)
这是实现您想要的目标的一种方法:
type MyType = { name: string }
// This function does nothing. It just helps with typing
const makeMyType = <T extends MyType>(o: T) => o
const x = makeMyType({
name: 'test', // Autocompleted, typesafe
} as const)
x.name // type is 'test' (not string)
Run Code Online (Sandbox Code Playgroud)
不需要类型检查,{name: "test"} as const因为 Typescript 使用结构相等的含义,只要{name: "test"} as constMyType 的结构相同,它们就相等,因此是相同的。
使用这些辅助类型可以观察到此行为。
interface MyType {
name: string;
}
const test = {name: "test"} as const;
type IsEqual<T, U> = [T] extends [U] ? true : false;
type AreTheyEqual = IsEqual<typeof test, MyType> // true they are the same.
Run Code Online (Sandbox Code Playgroud)
任何采用 MyType 的东西都可以采用 typeof Test。
编辑:如果您想强制测试为 MyType 类型以进行类型检查测试,则不能通过保留字符串文字来做到这一点,因为任何断言为 MyType 的内容都会丢失文字类型并回退到字符串,可以在此处观察到此行为。
type MyType = {name: string};
const x:MyType = {
name: 'test' as const
}
type Test = typeof x["name"] // string;
Run Code Online (Sandbox Code Playgroud)
这意味着如果您想在 MyType 上同时拥有文字和字符串类型,您将需要执行类似的操作(更改 MyType)。请注意,使用它似乎很冗长,但可以说比“as const”更少样板
interface MyType<NAME extends string = string> {
name: NAME;
}
const x: MyType = {
name: 'test' // string;
}
const y: MyType<"test"> = {
name: "test" // "test"
}
type Test1 = typeof x["name"]// string;
type Test = typeof y["name"] // "test";
Run Code Online (Sandbox Code Playgroud)
^ 允许字符串和文字类型。