我正在try 实现一个UI,在该UI中,客户端可以使用许多属性中的任何一个进行搜索.AFAIK这可以通过联合类型来实现.到目前为止,我的实现如下所示

interface GivenNameSearchTerm {
    readonly givenName: string;
}

interface FamilyNameSearchTerm {
    readonly familyName: string;
}

type SearchTerm = GivenNameSearchTerm | FamilyNameSearchTerm;

const search = (input: SearchTerm): Results[] => {
  // do stuff
}

现在,我想通过允许用户 Select 要搜索的属性及其值来调用search函数.

根据this other question,可以使用条件类型来缩小可能键的范围

type SearchInput<T> = T extends T ? keyof T : never;

const test = (key: SearchInput<SearchTerm>, value: string) => {
    search({ [key]: value });
}

这种方法使我可以缩小key可以具有的值,只允许givenNamefamilyName,但TypeScrip显示以下错误:

TS2345: Argument of type  { [x: string]: string; }  is not assignable to parameter of type  SearchTerm 
Property  familyName  is missing in type  { [x: string]: string; }  but required in type  FamilyNameSearchTerm

如果我硬编码的关键一切工作,但用户应该能够 Select 它.任何 idea ?

我查看了关于narrowing的文档,但在本例中,我不需要缩小类型,只需接受任何联合类型.虽然通过缩小类型没有错误,但这会导致重复代码:

const test = (key: SearchInput<SearchTerm>, value: string) => {
  switch (key) {
    case 'givenName':
      search({ [key]: value });
      break;
    case 'familyName':
      search({ [key]: value });
      break;
  }
}

推荐答案

可以使用以下命令强制转换类型:

search({ [key]: value } as {[key in typeof key]: typeof value});

interface GivenNameSearchTerm {
    readonly givenName: string;
}

interface FamilyNameSearchTerm {
    readonly familyName: string;
}

type SearchTerm = GivenNameSearchTerm | FamilyNameSearchTerm;

const search = (input: SearchTerm): Results[] => {
// do stuff
return "";
}

type SearchInput<T> = T extends T ? keyof T : never;

const test = (key: SearchInput<SearchTerm>, value: string) => {
    search({ [key]: value } as {[key in typeof key]: typeof value});
}

test("inValid", "asd"); // TS error: Argument of type '"inValid"' is not assignable to parameter of type '"givenName" | "familyName"'.
test("givenName", "asd");  // Pass

Typescript相关问答推荐

为什么在TypScript中写入typeof someArray[number]有效?

当方法参数和返回类型不相互扩展时如何从类型脚本中的子类推断类型

类型脚本基于数组作为泛型参数展开类型

为什么不能使用$EVENT接收字符串数组?

有没有可能为这样的函数写一个类型?

MatTool提示在角垫工作台中不起作用

如果数组使用Reaction-Hook-Form更改,则重新呈现表单

在排版修饰器中推断方法响应类型

为什么我的导航在使用Typescript的React Native中不起作用?

我在Angular 17中的environment.ts文件中得到了一个属性端点错误

类型推断对React.ForwardRef()的引用参数无效

Typescript -返回接口中函数的类型

如何从对象或类动态生成类型

如何创建内部和外部组件都作为props 传入的包装器组件?

Cypress-验证别名的存在或将别名中的文本与';if';语句中的字符串进行比较

VUE 3类型';字符串';不可分配给类型';参考<;字符串&>

推断集合访问器类型

类型';只读<;部分<;字符串|记录<;字符串、字符串|未定义&>';上不存在TS 2339错误属性.属性&q;x&q;不存在字符串

为什么`map()`返回类型不能维护与输入相同数量的值?

从泛型对象数组构造映射类型