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

TypeScript如何根据键为Record的值指定特定类型?

解决TypeScript中Filter类型的精准类型推断问题

你想要构建一个键为string类型、值属于string | number | boolean联合类型的结构,但当前实现会让编译器把值推断成具体的字面量类型(比如""或true),而非你期望的宽泛基础类型(string或boolean)。

问题分析

现有代码中,TypeScript会根据初始值的字面量自动推断出更具体的类型,导致访问属性时得到的是字面量类型而非对应的基础类型。要解决这个问题,需要手动将字面量类型拓宽到对应的基础类型。

解决方案

通过工具类型结合泛型函数,实现类型的自动拓宽:

  1. 定义基础类型和类型拓宽工具
type FilterKey = string;
type FilterValue = string | number | boolean;

// 将字面量类型拓宽到对应的基础类型
type WidenFilterValue<T> = 
  T extends string ? string :
  T extends number ? number :
  T extends boolean ? boolean :
  never;

// 构建最终的Filters类型,对每个属性应用类型拓宽
type Filters<T extends Record<FilterKey, FilterValue>> = {
  [K in keyof T]: WidenFilterValue<T[K]>;
};
  1. 改造工具函数
    不管是useFilters还是buildFilters,都基于泛型T接收初始值,返回拓宽后的Filters<T>类型:
import { useState } from 'react';

function useFilters<T extends Record<FilterKey, FilterValue>>(initialValue: T): Filters<T> {
  const [filters, setFilters] = useState<Filters<T>>(initialValue as Filters<T>);
  return filters;
}

function buildFilters<T extends Record<FilterKey, FilterValue>>(input: T): Filters<T> {
  return input as Filters<T>;
}
  1. 使用示例
const filters = buildFilters({ search: "", active: true });

// 现在类型推断符合预期:
filters.search; // 类型为string
filters.active; // 类型为boolean

// 可以正常赋值对应类型的值
filters.search = "typescript";
filters.active = false;

原理说明

WidenFilterValue工具类型通过条件判断,将传入的字面量类型(比如""、true)映射到对应的基础类型(string、boolean)。Filters类型则通过映射遍历输入对象的所有键,为每个属性应用类型拓宽逻辑。函数中的类型断言是为了告诉TypeScript,我们需要将初始的字面量类型转换为拓宽后的基础类型。

内容的提问来源于stack exchange,提问作者Andrew Possardt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 10:14:51