DeepReadonly对象打字稿 [英] DeepReadonly Object Typescript
问题描述
可以这样创建DeepReadonly
类型:
type DeepReadonly<T> = {
readonly [P in keyof T]: DeepReadonly<T[P]>;
};
interface A {
B: { C: number; };
D: { E: number; }[];
}
const myDeepReadonlyObject: DeepReadonly<A> = {
B: { C: 1 },
D: [ { E: 2 } ],
}
myDeepReadonlyObject.B = { C: 2 }; // error :)
myDeepReadonlyObject.B.C = 2; // error :)
太好了. B
和B.C
均为只读.但是,当我尝试修改D
...
This is great. Both B
and B.C
are readonly. When I try to modify D
however...
// I'd like this to be an error
myDeepReadonlyObject.D[0] = { E: 3 }; // no error :(
我应该如何编写DeepReadonly
,以使嵌套数组也只读?
How should I write DeepReadonly
so that nested arrays are readonly as well?
推荐答案
从TypeScript 2.8开始,这已经成为可能,实际上是PR中条件类型的示例:
As of TypeScript 2.8, this is now possible and actually an example in the PR for Conditional Types: https://github.com/Microsoft/TypeScript/pull/21316
另请参阅关于条件类型的类型推断的注释: https://github.com/Microsoft/TypeScript/pull/21496
Also see the notes on type inference for Conditional Types: https://github.com/Microsoft/TypeScript/pull/21496
我稍微修改了示例以对只读数组值类型使用类型推断,因为我发现(infer R)[]
比Array<T[number]>
更清晰,但是两种语法都可以.我还删除了示例NonFunctionPropertyNames
位,因为我想保留输出中的功能.
I modified the example slightly to use the type inference for the readonly array value type because I find (infer R)[]
clearer than Array<T[number]>
but both syntaxes work. I also removed the example NonFunctionPropertyNames
bit as I want to preserve functions in my output.
type DeepReadonly<T> =
T extends (infer R)[] ? DeepReadonlyArray<R> :
T extends Function ? T :
T extends object ? DeepReadonlyObject<T> :
T;
interface DeepReadonlyArray<T> extends ReadonlyArray<DeepReadonly<T>> {}
type DeepReadonlyObject<T> = {
readonly [P in keyof T]: DeepReadonly<T[P]>;
};
以这种方式进行DeepReadonly还会保留可选字段(感谢Mariusz告知我),例如:
Doing DeepReadonly this way also preserves optional fields (thanks to Mariusz for letting me know), e.g.:
interface A {
x?: number;
y: number;
}
type RA = DeepReadonly<A>;
// RA is effectively typed as such:
interface RA {
readonly x?: number;
readonly y: number;
}
尽管在某些情况下TS仍然有一些简单的方法来失去只读性",但这与您将获得的C/C ++样式const
值一样接近.
While TS still has some easy ways to lose "readonly-ness" in certain scenarios, this is as close to a C/C++ style const
value as you will get.
这篇关于DeepReadonly对象打字稿的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!