如何判断联合类型T | [string, T][]是否为T而非[string, T][]?
解决方案
要实现这个类型判断,核心是结合运行时类型检查和TypeScript的类型守卫——毕竟TS类型在编译后会被擦除,必须靠运行时逻辑区分两种类型。
步骤1:编写运行时结构判断函数
先写一个辅助函数,判断输入是否符合[string, T][]的结构:
function isStringTupleArray<T>(value: unknown): value is [string, T][] { // 先排除非数组情况 if (!Array.isArray(value)) return false; // 遍历每一项,检查是否是长度为2的数组且第一项为字符串 return value.every(item => Array.isArray(item) && item.length === 2 && typeof item[0] === 'string' ); }
步骤2:实现类型区分的核心函数
基于上面的辅助函数,就能写出区分T和[string, T][]的类型守卫:
function isType<T>(value: T | [string, T][]): value is T { return !isStringTupleArray(value); }
实际使用示例
针对你提到的T = null场景:
const example1: null | [string, null][] = [['addr1', null], ['addr2', null]]; console.log(isType(example1)); // false,属于数组类型 const example2: null | [string, null][] = null; console.log(isType(example2)); // true,属于null类型
再测试其他T类型的情况:
// T = string const strOrArray: string | [string, string][] = 'hello'; console.log(isType(strOrArray)); // true const tupleArray1: string | [string, string][] = [['name', 'Alice'], ['age', '30']]; console.log(isType(tupleArray1)); // false // T = string[] const arrOrTupleArray: string[] | [string, string[]][] = ['a', 'b', 'c']; console.log(isType(arrOrTupleArray)); // true const tupleArray2: string[] | [string, string[]][] = [['tags', ['js', 'ts']], ['langs', ['cn', 'en']]]; console.log(isType(tupleArray2)); // false
方案优势
- 不依赖T的构造函数,适配基本类型(string、number、null)和数组类型
- 无需额外传入示例对象,完全靠结构判断实现,符合TS的类型推断逻辑
- 类型守卫能让TS在后续代码中自动识别类型:
function handleValue<T>(value: T | [string, T][]): void { if (isType(value)) { // TS自动推断value为T类型 console.log('处理单个值:', value); } else { // TS自动推断value为[string, T][]类型 console.log('处理键值对数组:', value); } }
内容的提问来源于stack exchange,提问作者Adan Wattad
相关产品推荐
相关产品推荐

