首页 > 解决方案 > 如何在 TypeScript 中键入函数参数以映射对象属性?

问题描述

我试图了解如何正确地将类型设置为propvalue函数参数(请参阅??),以便 prop 和 value 必须与MyStorage接口中定义的相匹配。设置keyof MyStorage应该足以正确键入prop,但是我完全不知道如何键入value

interface MyStorage {
  prop1?: string;
  prop2?: number;
  prop3?: boolean;
  prop4?: Array<string>;
  prop5?: 'value1' | 'value2';
}

const myStorage: MyStorage = {};

const setProp = (prop: ??, value: ??) => {
  myStorage[prop] = value;
}

setProp('prop1', 'Ok');
setProp('prop1', 5); // Not Ok
setProp('prop5', 'value1'); // Ok
setProp('prop5', 'value5'); // Not Ok

最终目标是将此函数转换为这样的通用版本:

const genericSetProp = <T>(prop: ??, value: ??, storage: T) => {
  storage[prop] = value;
}

genericSetProp('prop1', 'Ok', myStorage);
genericSetProp('prop1', 5, myStorage); // Not Ok
genericSetProp('prop5', 'value1', myStorage); // Ok
genericSetProp('prop5', 'value5', myStorage); // Not Ok

如何设置这些类型以使 TypeScript 正确检查这些参数?

标签: typescript

解决方案


您可以通过执行等操作来使用结构成员的类型MyStorage["prop1"]。要获取该"prop1"部分,您可以要求keybe keyof MyStorage。所以第一个版本看起来像这样:

const setProp = <K extends keyof MyStorage>(prop: K, value: MyStorage[K]) => {
    myStorage[prop] = value;
};

您确实可以通过MyStorage使用第二个泛型类型参数从第三个参数推断类型来使该泛型:

const genericSetProp = <T, K extends keyof T>(prop: K, value: T[K], storage: T) => {
    storage[prop] = value;
};

游乐场链接


推荐阅读