javascript - 是否有办法在声明类型时根据另一个数组的大小强制数组大小声明?
我需要为函数参数定义一个接口。假设我们有两个参数,它们的类型都是array,其中一个依赖于另一个的长度以及包含元素的类型(元素类型相同)。
有没有办法将其中一个声明得和另一个一样长?
答案#1
更新 2022年1月30日
有一种更简单且不那么啰嗦的方法来做这件事:
type Json =
| null
| string
| boolean
| number
| { [prop: string]: Json }
| Array<Json>
function array<
Elem,
First extends Elem[],
>(x: [...First], y: [...First]) {
}
/**
* Passed
*/
{
const _ = array([1, 2, 3], [1, 1, 1]) // ok
const __ = array(['a', 'b', 'c'], ['x', 'x', 'x']) // ok
}
/**
* Failed
*/
{
const __ = array([1, 2, 3], [1, 1, 1, 1]) //expected error
const ___ = array([1, 2, 3], ['a', 'b', 'c']) //expected error
const ____ = array([1], []) //expected error
const _____ = array([], [1]) //expected error
}
操场
在这里你可以找到非常相似的答案
在这里您可以找到关于函数参数推断的更多信息
过于冗长且无效的方式
给你:
type ArrayElement = number;
type Array1D = ReadonlyArray<ArrayElement>;
type MutableLength = unknown[]["length"]; // number
export type Length<T extends ReadonlyArray<any>> = T extends { length: infer L }
? MutableLength extends L
? MutableLength
: L
: MutableLength;
type CompareLength<
X extends ReadonlyArray<any>,
Y extends ReadonlyArray<any>
> = MutableLength extends Length<X>
? false
: MutableLength extends Length<Y>
? false
: Length<X> extends Length<Y>
? true
: false;
type CompareType<
X extends ReadonlyArray<any>,
Y extends ReadonlyArray<any>
> = X[number] extends Y[number] ? true:false
function array<
X extends Array1D,
Y extends {
0: Array1D
}[CompareLength<X,Y> extends true? CompareType<X,Y> extends true ?0 : never:never],
>(x: X, y: Y) {
}
const result = array([1, 2, 3] as const, [1, 2, 3] as const) // ok
const result2 = array([1, 2, 3] as const, [1, 2, '3'] as const) // error
const result3 = array([1, 2, 3] as const, [1, 2] as const) // error
const result4 = array([1, 2, 3] as const, [] as const) // error
const result5 = array([1, 2, 3] as const, []) // error
const result6 = array([], []) // error, because arrays are mutable. TS is unable to find out the length
操场
这是我的文章,在这里你可以找到更多解释
请记住,您应仅对只读数组进行操作。
