`as const` 替代缩小数组文字元组,以避免 `readonly` 修饰符

ten*_*its 13 typescript typescript-typings

我们用来as const缩小类型:

[ {foo: 'foo' }, { bar: 'bar' } ] as const
Run Code Online (Sandbox Code Playgroud)

但这也readonly为所有道具和值添加了修饰符。到目前为止const,这是有道理的,但我希望缩小范围,不使用readonly修饰符,因为您通常想要修改元组中的对象,或者只是将其进一步传递给某个方法,该方法具有相同的接口,但没有深层readonly

let foo = [ {foo: 'foo' }, { bar: 'bar' } ]
Run Code Online (Sandbox Code Playgroud)

这里 foo 的类型是:

({
    foo: string;
    bar?: undefined;
} | {
    bar: string;
    foo?: undefined;
})[]
Run Code Online (Sandbox Code Playgroud)

但我希望得到

[{
    foo: string;
}, {
    bar: string;
}]
Run Code Online (Sandbox Code Playgroud)

我们使用as const,但在大多数情况下这是不可能的,因为foo/bar得到深度嵌套的readonly修饰符,我们可以使用类似的东西

type DeepWritable<T> = { -readonly [P in keyof T]: DeepWritable<T[P]> };
Run Code Online (Sandbox Code Playgroud)

但它会被连接到使用as constwhichadds readonly,然后DeepWritable删除它。

您是否知道as const无需手动定义类型即可缩小元组类型的任何替代方法。

cca*_*ton 7

您可以使用以下泛型函数将类型约束为元组:

const Tuple = <T extends [any, ...any]>(v:T) => v
Run Code Online (Sandbox Code Playgroud)

然后将文字换行:

let foo = Tuple([ {foo: 'foo' }, { bar: 'bar' } ]) // foo: [{ foo: string }, { bar: string }]
Run Code Online (Sandbox Code Playgroud)