Ben*_*arp 6 typescript typescript-typings
我想将对象限制为某种类型,但也想将其转换为“const”,以便可以按字面意思键入某些属性。但是,当我将“as const”与下面的代码中的类型定义一起使用时,推断的类型不是文字——“as const”被忽略。
interface IFilterBase {
type: string
...
}
const COST_FILTER: IFilterBase = {
type: "cost",
...
} as const
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,“as const”被忽略了。COST_FILTER.type被推断为string,而不是"cost"。
有没有办法限制COST_FILTER为实现IFilterBase类型,但它的属性被推断为“作为常量”?
如果您明确指定类型 typescript 将只检查与接口的兼容性。评论中概述了一项提案,以支持该语言。
在此之前,我们可以使用函数、元组和文字的推理规则:
[unknown] | unknown[]。有了这些规则,我们就可以创建一个递归映射类型,将原始类型的属性映射到包含此类泛型类型参数的新类型。我们不会为每个属性分离类型参数,一个参数用于文字,一个用于元组。这足以向编译器提示我们想要什么。
type WithLiterals<T, L, LTuple> =
T extends string| number | boolean | null | undefined ? T & L :
{
[P in keyof T]:
WithLiterals<T[P], L, LTuple> & (T[P] extends Array<any> ? LTuple: unknown)
}
type DeepReadonly<T> = {
readonly [P in keyof T]: DeepReadonly<T[P]>
}
function asConst<TInterface>()
{
return function<
LTuple extends [unknown] | unknown[],
L extends string | boolean | number, T extends WithLiterals<TInterface, L, LTuple>>(o: T): DeepReadonly<T> {
return o as any
}
}
type IFilterBase = {
type: "cost" | "other",
displayName: string | undefined,
nr: number,
nrUnion: 1 | 2,
subObj : {
a: string;
}
arr: string[]
larr: ("A" | "B")[]
mixedarr: (number | string)[],
oArray: Array<{
a: string
}>
}
export const COST_FILTER = asConst<IFilterBase>()({
type: "other",
nr: 1,
nrUnion: 1,
displayName: "Cost",
subObj: {
a: "A"
},
arr: ["A", "B"],
larr: ["A"],
mixedarr: [1, ""],
oArray: [
{ a: ""}
]
})
Run Code Online (Sandbox Code Playgroud)
键入为:
export const COST_FILTER : DeepReadonly<{
type: "other";
nr: 1;
nrUnion: 1;
displayName: "Cost";
subObj: {
a: "A";
};
arr: ["A", "B"];
larr: ["A"];
mixedarr: [1, ""];
oArray: [{
a: "";
}];
}>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
389 次 |
| 最近记录: |