[英]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.