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

TypeScript:如何基于对象属性键类型约束属性值类型?

解决TypeScript中关联属性名与属性值类型的问题

问题分析

你之前的方案失败是因为keyof StoreState生成的是键的联合类型,此时propValue会被推断为所有对应值类型的联合,无法和单个propName建立一一对应的约束关系——也就是说,TypeScript无法确保你传入的propValue和propName是匹配的。

解决方案:泛型函数约束

使用泛型捕获具体的属性键,让propValue的类型严格对应propName对应的StoreState属性类型:

type StoreState = {
  admins: Admin[];
  messages: Message[];
  pageInformation: PageInformation;
}

const state: StoreState = {
  admins: [],
  messages: [],
  pageInformation: {},
}

// 泛型函数:K 代表 StoreState 的某个具体键
const setPropertyValue = <K extends keyof StoreState>({ 
  propName, 
  propValue 
}: { 
  propName: K; 
  propValue: StoreState[K] 
}) => {
  state[propName] = propValue;
};

正确调用示例

// 符合类型约束,正常通过
setPropertyValue({ propName: "admins", propValue: [{ id: 1, name: "admin" } as Admin] });
setPropertyValue({ propName: "pageInformation", propValue: { title: "Home" } as PageInformation });

// 类型不匹配,TypeScript会报错
setPropertyValue({ propName: "admins", propValue: ["hello"] }); // 错误:string[] 不能赋值给 Admin[]

扩展:Redux Reducer的实现

如果你要把这个逻辑迁移到Redux reducer中,可以通过映射类型生成联合action类型来保证类型安全:

// 生成所有可能的SET_PROPERTY action类型
type SetPropertyAction = {
  [K in keyof StoreState]: {
    type: 'SET_PROPERTY';
    payload: {
      propName: K;
      propValue: StoreState[K];
    };
  };
}[keyof StoreState];

const reducer = (state: StoreState, action: SetPropertyAction): StoreState => {
  switch (action.type) {
    case 'SET_PROPERTY':
      return {
        ...state,
        [action.payload.propName]: action.payload.propValue
      };
    default:
      return state;
  }
};

这种写法会让TypeScript自动检查action的payload是否匹配:当propName为"admins"时,propValue必须是Admin[]类型,完全符合你的需求。


内容的提问来源于stack exchange,提问作者Király József

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 10:57:36