网站搜索

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

操场

这是我的文章,在这里你可以找到更多解释

请记住,您应仅对只读数组进行操作。

相关文章