[英]Use “as const” in Typescript without adding “readonly” modifiers?
If I want to define a tuple or constant object shape, I'd use as const
.如果我想定义一个元组或常量对象形状,我会使用
as const
。 Eg:例如:
const arr = [{ a: 1 }] as const;
/* readonly [{
readonly a: 1;
}] */
However, I don't want readonly
because I'd get a lot of The type 'readonly ...' is 'readonly' and cannot be assigned to the mutable type '...'
但是,我不想要
readonly
因为我会得到很多The type 'readonly ...' is 'readonly' and cannot be assigned to the mutable type '...'
I defined a "Mutable" generic:我定义了一个“可变”泛型:
type Mutable<T> = {
-readonly [K in keyof T]: Mutable<T[K]>;
}
type Arr = Mutable<typeof arr>;
/* [Mutable<{
readonly a: 1;
}>] */
However, TS doesn't recursively apply Mutable
in VS Code's type preview.但是,TS 不会在 VS Code 的类型预览中递归应用
Mutable
。 In other words, I want VS Code's type preview to show:换句话说,我希望 VS Code 的类型预览显示:
/* [{
a: 1;
}] */
I don't think it's possible for VS Code to recursively evaluate Mutable
, since it could be too slow.我认为 VS Code 不可能递归评估
Mutable
,因为它可能太慢了。
Is there something like as const
, but without adding readonly
?是否有类似于
as const
东西,但没有添加readonly
?
In fact, you already made this array mutable.事实上,您已经使这个数组可变。 But you probably have noticed that type of first element is
{a: 1}
但是你可能已经注意到第一个元素的类型是
{a: 1}
const arr = [{ a: 1 }] as const;
type Mutable<T> = {
-readonly [K in keyof T]: Mutable<T[K]>;
}
type Arr = Mutable<typeof arr>[0]; // {a: 1}
Because a
has literal type number 1
, you still can't mutate the element.因为
a
文字类型编号为1
,所以您仍然无法改变元素。
Sorry, you can, but you are allowed to use only 1
抱歉,您可以,但您只能使用
1
const x: Arr = [{ a: 1 }]
x[0].a = 1 // ok
In order to make it fully mutable, you should map all literal types to more commont types.为了使其完全可变,您应该将所有文字类型映射到更常见的类型。
1
-> number
1
-> number
type LiteralToCommon<T extends PropertyKey> =
T extends number
? number : T extends string
? string : T extends symbol
? symbol : never;
type Mutable<T> = {
-readonly [K in keyof T]: T[K] extends PropertyKey ? LiteralToCommon<T[K]> : Mutable<T[K]>;
}
const arr = [{ a: 1 }] as const;
type Arr = Mutable<typeof arr>;
const x: Arr = [{ a: 1 }]
x[0].a = 10 // ok
There is an alternative way:有一种替代方法:
type Mutable<T> = {
-readonly [K in keyof T]: Mutable<T[K]>;
}
const arr = [{ a: 1 }];
type ImmutableArr = Readonly<typeof arr>
type MutableArr = Mutable<ImmutableArr>
type Arr = Mutable<typeof arr>;
const x: MutableArr = [{ a: 1 }]
x[0].a = 10 // ok
You can use just Readonly
for array.您可以仅将
Readonly
用于数组。 This util will infer {a: 1}
as {a: number}
此实用程序会将
{a: 1}
推断为{a: number}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.