You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现TypeScript类型UniqueK<T>,校验类型中k字段值的唯一性?

TypeScript类型工具:检查字段k值的唯一性

需求概述

  • 给定一组类型(如元组、联合类型),检查每个类型的字段k是否具有唯一值
  • 实现类型UniqueK<T>,判断T中是否存在至少两个类型的k值重复;若存在非字面量数字类型(如number、any、7|8),理想返回false(该要求非强制)

预期行为示例:

type UniqueK<T extends ...> = ... ? true : false;

// 预期结果
UniqueK<[{k:1}, {k:2}]>         = true
UniqueK<[{k:7}, {k:42}, {k:0}]> = true
UniqueK<[{k:1}, {k:1}]>         = false // k:1重复
UniqueK<[{k:7}, {k:42}, {k:7}]> = false // k:7重复
UniqueK<[{k:number}, {k:1}]>    = false // 包含非字面量数字类型

实现方案

核心思路

  1. 提取集合中所有元素的k字段类型,组成联合类型
  2. 验证所有k类型均为字面量数字
  3. 比较原集合的元素数量与k联合类型的元素数量:若相等则无重复,否则存在重复

完整类型代码

// 提取集合中所有元素的k字段类型
type ExtractK<T> = T extends { k: infer K } ? K : never;

// 判断是否为字面量数字类型
type IsLiteralNumber<T> = T extends number ? (number extends T ? false : true) : false;

// 计算联合类型的元素个数
type UnionLength<T, Acc extends unknown[] = []> = 
  T extends never 
    ? Acc['length'] 
    : UnionLength<Exclude<T, T>, [...Acc, unknown]>;

// 核心类型:检查k值唯一性
type UniqueK<T extends readonly { k: number }[]> = 
  ExtractK<T[number]> extends infer K 
    ? (IsLiteralNumber<K> extends false 
      ? false 
      : (T['length'] extends UnionLength<K> ? true : false))
    : false;

测试用例验证

type Test1 = UniqueK<[{k:1}, {k:2}]>;         // true
type Test2 = UniqueK<[{k:7}, {k:42}, {k:0}]>; // true
type Test3 = UniqueK<[{k:1}, {k:1}]>;         // false
type Test4 = UniqueK<[{k:7}, {k:42}, {k:7}]>; // false
type Test5 = UniqueK<[{k:number}, {k:1}]>;    // false
type Test6 = UniqueK<[{k:7|8}, {k:9}]>;       // false

代码说明

  • ExtractK:通过条件类型推断,提取所有元素的k字段类型,最终得到这些类型的联合集合
  • IsLiteralNumber:区分字面量数字(如1)和非字面量数字类型(如number、7|8):若number可以赋值给T,说明T是宽泛的数字类型,返回false
  • UnionLength:利用递归和Exclude操作,逐个移除联合类型的元素,通过累加数组长度来计算联合类型的元素数量
  • UniqueK:先验证所有k都是字面量数字,再比较原元组的长度与k联合类型的长度——长度相等意味着没有重复的k值,返回true;否则返回false

内容的提问来源于stack exchange,提问作者Blue Nebula

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 14:18:33