【问题标题】:Typescript: check key and type combination of any interface property separately as function arguments打字稿:分别检查任何接口属性的键和类型组合作为函数参数
【发布时间】:2020-03-19 00:53:43
【问题描述】:

给定一个带有接口的变量:

interface Model {
  textField?: string;
  hasMeaning: boolean;
  percentage: number;
  readonly someMap: {
    [key: string]: string;
  };
  getMeSomething(code: string): string;
}

let model: Model;

我想在这个函数中分别检查键名和值类型:

const setField = (fieldName: WritableKeysOf<Model>, fieldValue: Model[WritableKeysOf<Model>]) => {
  model[fieldName] = fieldValue;
}

所以当我这样使用它时:

setField('textField', 1);
setField('non-existant', true);
setField('someMap', { 'it': 'does not matter' });

我收到错误,但这些不会有问题:

setField('textField', undefined);
setField('percentage', 2);
setField('getMeSomething', code => code + 'suffix');

我想实现:

  • fieldName 应该匹配任何接口道具名称,但与 readonly 匹配 ✔️
  • fieldValue 应匹配界面中任何可能的类型,但与 readonly 匹配的类型 ✔️
  • 将两者结合起来,这样我就可以设置一个值而不会出错❌

我发现了一些技巧来删除readonly 并正确获取两个参数的类型,但由于某种原因,model[fieldName] 现在是never。也许我可以使用一些泛型来告诉我到底要检查哪个接口道具?

TS Playground

【问题讨论】:

  • setField&lt;T extends WritableKeysOf&lt;Model&gt;&gt;(key: T, value: Model[T])

标签: typescript interface


【解决方案1】:

作为Ingo Bürk has suggested,您可以引入约束类型参数以将fieldValue 的类型与各自的fieldName 相关联:

const setField = <T extends WritableKeysOf<Model>> (fieldName: T, fieldValue: Model[T]) => {
  model[fieldName] = fieldValue;
}

【讨论】:

    猜你喜欢
    • 2021-11-13
    • 2019-06-20
    • 2023-03-30
    • 2017-09-16
    • 2022-11-11
    • 2019-11-05
    • 1970-01-01
    • 2020-05-11
    • 2018-07-14
    相关资源
    最近更新 更多