如何在TypeScript中定义含不同泛型参数的CompareOp数组类型?
在TypeScript中定义包含任意类型CompareOp实例的数组类型
首先我们有如下泛型接口:
interface CompareOp<T> { a: T; b: T; cmp: (v1: T, v2: T) => number; }
我们需要定义一个数组类型,要求数组中的每个元素可以是任意类型的CompareOp实例,但必须保证单个元素内部的cmp函数参数类型与a、b的类型完全匹配。例如:
有效示例
[ {a: 1, b: 1, cmp: (v1: number, v2: number) => v1 - v2}, {a: 'a', b: 'b', cmp: (v1: string, v2: string) => v1.localeCompare(v2)} ]
无效示例(应触发类型错误)
[ {a: 1, b: 1, cmp: (v1: string, v2: string) => v1.localeCompare(v2)}, {a: 'a', b: 'b', cmp: (v1: number, v2: number) => v1 - v2} ]
实现方案
TypeScript没有直接的“存在类型”语法来直接定义这种数组类型,但可以通过以下方式实现需求:
1. 泛型函数推导(推荐)
通过定义泛型函数,让TypeScript自动推导数组中每个元素的具体T类型,从而严格约束每个元素内部的类型一致性:
function createCompareOps<T extends unknown[]>(...ops: { [I in keyof T]: CompareOp<T[I]> }): typeof ops { return ops; } // 有效:类型检查通过,数组类型被推导为 [CompareOp<number>, CompareOp<string>] const validOps = createCompareOps( {a: 1, b: 1, cmp: (v1: number, v2: number) => v1 - v2}, {a: 'a', b: 'b', cmp: (v1: string, v2: string) => v1.localeCompare(v2)} ); // 无效:TypeScript会直接报错,提示cmp函数参数类型与a、b不匹配 const invalidOps = createCompareOps( {a: 1, b: 1, cmp: (v1: string, v2: string) => v1.localeCompare(v2)}, {a: 'a', b: 'b', cmp: (v1: number, v2: number) => v1 - v2} );
2. 直接定义数组类型(不推荐)
如果不需要严格的类型检查,可以直接使用Array<CompareOp<any>>,但这种方式会绕过TypeScript的类型校验,无法拦截无效示例:
type LooseCompareOpArray = Array<CompareOp<any>>;
3. 联合类型数组(有限场景)
如果只需要支持预先确定的几种T类型,可以用联合类型数组:
type FixedCompareOpArray = Array<CompareOp<number> | CompareOp<string> | CompareOp<boolean>>;
这种方式的局限性是无法支持任意类型的CompareOp实例,只能覆盖指定的类型范围。
内容的提问来源于stack exchange,提问作者Plargato
相关产品推荐
相关产品推荐

