繁体   English   中英

Typescript:缩小映射类型不适用于 generics

[英]Typescript: Narrowing down mapped types does not work with generics

问题:我想编写一个 function ,它将 object 和属性名称作为参数。 我想要实现的是只接受具有特定类型的属性的属性名称。

示例:在一个人 object 中,我有字段名称:字符串和年龄:数字,我的 function 应该只能使用参数(person,'name')调用。 这可以通过创建这种类型来实现:

export type OnlyPropertiesWithSpecificType<TYPE, T> = {
  [K in keyof T]: T[K] extends TYPE ? K : never;
}[keyof T];

在访问 function 中的属性时,属性值的类型应受到如下约束:

type Person = {
  name: string;
  age: number;
};

function somePersonFunction(obj: Person, param: OnlyPropertiesWithSpecificType<string, Person>): string {
  return obj[param]; // works, obj[param] is of type 'string'
}

但是,当我尝试生成 function 时,它不再受类型限制:

function someGenericFunction<T>(obj: T, param: OnlyPropertiesWithSpecificType<string, T>): string {
  return obj[param]; // doesn't work: "TS2322: Type 'T[{ [K in keyof T]: T[K] extends string ? K : never; }[keyof T]]' is not assignable to type 'string'."
}

这很令人困惑,因为编译器仍然只接受属于“字符串”类型的属性的属性名称作为参数:

someGenericFunction(person, 'name'); // works
someGenericFunction(person, 'age'); // doesn't work

我尝试了什么:

  • TS 版本 3.4.5 和 4.1.2。
  • T 的各种变体,即 T 扩展 object

我用上面的例子创建了一个沙箱: https://codesandbox.io/s/typescript-forked-ypy0b

我该如何解决这个问题?

看起来 TS 还没有弄清楚someGenericFunction总是会返回一个string ,即使在实践中它总是会。

但是,除非您绝对需要someGenericFunction: string返回类型注释,否则您可以省略它,您的代码将按预期工作。

function someGenericFunction<T>(
  obj: T,
  param: OnlyPropertiesWithSpecificType<string, T>
) {
  return obj[param]; // inferred return type is T[OnlyPropertiesWithSpecificType<string, T>]
}

当使用实际类型调用时,TS 确实推断T[OnlyPropertiesWithSpecificType<string, T>]将始终可分配给string ,这就是函数起作用的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM