在给定如下所示的接口A的情况下,我们设想提供查找函数以返回每个值的外部服务.

interface A {
    a: string;
    b: number;
    c: boolean;
}

显然,外部服务S将如下所示:

interface S {
    get(name: 'a'): string;
    get(name: 'b'): number;
    get(name: 'c'): boolean;
}

但如何将其表示为泛型类型构造S<A>-?

也许我们可以从观察到下面的声明在功能上与上面的声明相同开始:

type S = {
    get: ((name: 'a') => string) & ((name: 'b') => number) & ((name: 'c') => boolean))
}

它的用法如下:

const c = service.get('c');  // 'c' would be type boolean here.

我try 从keyof A开始构建,并使用以下帮助器从union移动到intersection:

type UnionToIntersection<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

但这就是我被困的地方.帮助!

推荐答案

正如@jcalz提到的,单一的generic方法将更加简单和简洁.我们将创建接受A类型的S,并将添加一个泛型方法,该方法将接受另一个泛型参数,该参数将被约束为A‘S键,并且通过使用indexed access,我们将获得正确的类型:

type S<A> = {
  get<K extends keyof A>(name: K): A[K];
};

测试:

type Result = S<A>;

const service = {} as Result;

const a = service.get('a') // string
const b = service.get('b') // number
const c = service.get('c') // boolean

playground

Typescript相关问答推荐

React组件数组及其props 的类型定义

如何从具有给定键列表的对象类型的联合中构造类型

类型脚本接口索引签名

在TypeScrip中分配回调时,参数的分配方向与回调本身相反.为什么会这样呢?

TypeScrip 5.3和5.4-对`Readonly<;[...number[],字符串]>;`的测试版处理:有什么变化?

TS2339:类型{}上不存在属性消息

TypeScrip:来自先前参数的参数中的计算(computed)属性名称

使用2个派生类作为WeakMap的键

如何将定义模型(在Vue 3.4中)用于输入以外的其他用途

为什么ESLint会抱怨函数调用返回的隐式`any`?

将带点的对象键重新映射为具有保留值类型的嵌套对象

(TypeScript)TypeError:无法读取未定义的属性(正在读取映射)"

复选框Angular 在Ngfor中的其他块中重复

类型脚本-在调用期间解析函数参数类型

必需的输入()参数仍然发出&没有初始值设定项&q;错误

在类型脚本中创建显式不安全的私有类成员访问函数

如何避免多个类型参数重复?

两个名称不同的相同打字界面-如何使其干燥/避免重复?

TypeScript是否不知道其他函数内部的类型判断?

使用本机 Promise 覆盖 WinJS Promise 作为 Chrome 扩展内容脚本?