解构由另一个泛型构成的泛型类型

Deconstruct generic type which made from another generic

如果问题标题含糊不清,我们深表歉意。不确定如何最好地描述这个

假设我有这个通用接口

interface IPaginatedResponse<T> {
    results: T[],
    page: number,
    count: number
}

我有这个具体类型

type PaginatedUsers = IPaginatedResponse<User>

现在我想创建一个函数,它接收任何 type 的具体类型 IPaginatedResponse

// Invalid syntax

const myFn = <IPaginatedResponse<T>>() => {
 ...
 // Do something with T
}

这样我就可以发现输入错误

myFn<PaginatedUsers>()  // OK
myFn<User>()            // Fails

以上为伪代码

如果您的函数采用任何 IPaginatedResponse,您将希望您的函数采用 <T extends IPaginatedResponse<any>>。要访问内部类型,您可以使用 infer 键创建一个通用助手来提取您正在分页的类型:

type GetPaginatedType<T extends IPaginatedResponse<any>> = T extends IPaginatedResponse<infer R> ? R : never;

然后您可以使用该助手在您的函数中获取类型(或将其添加到您的 return 语句)。

type User = "user"
interface IPaginatedResponse<T> {
    results: T[],
    page: number,
    count: number
}
type PaginatedUsers = IPaginatedResponse<User>
type GetPaginatedType<T> = T extends IPaginatedResponse<infer R> ? R : never;
// this works
const user: GetPaginatedType<PaginatedUsers> = "user";

// this doesn't
const notUser: GetPaginatedType<PaginatedUsers> = "notuser";

const myFn = <T extends IPaginatedResponse<any>>() => {
  type MyInternalType = GetPaginatedType<T>;
}

myFn<PaginatedUsers>();
// this correctly errors
myFn<User>();

playground

您可能需要使用 extends

<T extends IPaginatedResponse<any>>