繁体   English   中英

如何在打字稿中制作通用类型来处理来自 API 响应的可选包含?

[英]How to make generic type in typescript that deals with optional includes from API response?

我有 Laravel 后端,我使用变压器。 这意味着我可以键入?include=reviews_count,author等以从后端获取其他数据。 有没有办法静态输入它?

当然,一种方法是创建一种 DTO 类型并且所有包含都是可选的,但这并不理想。

其他(我想出的)是拥有某种泛型类型,它将 DTO 作为第一个参数,将包含类型的联合作为第二个参数。 但是我遇到了 Typescript 设计限制问题,因为 Typescript 不能通过通用类型进行这种索引。

我想出的最后一件事是拥有某种看起来像这样的Includes类型

export type Includes<BaseClass, Includes> = {
  [T in keyof BaseClass]: BaseClass[T];
} &
  {
    [T in keyof Includes]: Includes[T];
  };

type TeacherDTO = {
  name: string;
  surname: string;
}

type TeacherIncludeNumber = {
  count: number;
}

type GetTeachersResponse = Includes<TeacherDTO, TeacherIncludeMember | ...>;

但它并没有真正起作用。 有什么可靠的处理方法吗?

好吧,你需要做一些事情。 使您的TeachDto类型包含所有可能的属性。 然后在函数的返回类型中使用Pick<T,R>类型映射,如下所示:

type TeacherDTO = {
    name: string;
    surname: string;
    number: string;
    gender: string;
    birthDate: Date
}

type TeacherKeys = keyof TeacherDTO;


function getTeacher<T extends TeacherKeys>(keys: T[]): Pick<TeacherDTO, T> {
     // implementation omitted for brevity
    return {} as any;
}


const finalTeacher = getTeacher(["name","number"]);

finalTeacher.name // ok
finalTeacher.number // ok
finalTeacher.gender // not ok



getTeacher(["foo"]) // not ok

游乐场链接

首先,您可以定义包含和基本教师 dto

type Includes = {
    count: number,
    author: { name: string, age: number }
}

type TeacherDTO = {
  name: string;
  surname: string;
}

然后,您可以使您的方法需要一个或多个包含,并根据这些包含定义您的最终数据类型(请注意Unarray取自此处

type Unarray<T> = T extends Array<infer U> ? U : T;

function getTeacher<TIncludes extends Array<keyof Includes>>(...args: TIncludes): TeacherDTO & Pick<Includes, Unarray<TIncludes>> {
    // your logic
    return {} as any;
}

var a = getTeacher();
a.name // works
a.surname // works
a.count // doesnt work
a.author // doesnt work

var b = getTeacher('author');
b.name // works
b.surname // works
b.author // works
b.count // doesnt work

var c = getTeacher('author', 'count');
c.name // works
c.surname // works
c.author // works
c.count // works

游乐场链接在这里

干杯。

暂无
暂无

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

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