如何从 class 属性 (在将 class 作为参数传递后)为计算的 属性 名称获取文字类型?
How to get a literal type from a class property (after passing the class as argument) for a computed property name?
刚才我问了 现在我有一个跟进:)
请考虑以下代码:
import { ClassConstructor } from "class-transformer";
import { useQuery as useApolloQuery } from "@apollo/client";
class Book {
readonly many = "books" as const;
bookData: any;
}
export const useQueryWrapper = <T>(cls: ClassConstructor<T>, queryString) => {
return useApolloQuery<{ [cls.prototype.many]: T[] }>(queryString);
};
const { data } = useQueryWrapper(Book, "..."); // Book or any other class with a literal `many` prop
TS 将数据识别为以下类型:
const data: {} | undefined
我想让 TS 知道数据有 属性 本书
const data: {
books: Book[];
} | undefined
可能吗?
这可以通过组合 index access types and mapped types (playground):
class Book {
readonly many = "books" as const;
bookData: any;
}
class Page {
readonly many = "pages" as const;
bookData: any;
}
type ManyType = { readonly many: string };
type QueryResult<T extends ManyType> = {
// using K in T["many"] to create an object with a key of value T["many"], e.g. "books", "pages", etc.
[K in T["many"]]: T[];
};
type ClassConstructor<T> = new (...args: any[]) => T;
function useQueryWrapper<T extends ManyType>(
cls: ClassConstructor<T>,
queryString: string
): QueryResult<T> | undefined {
return {} as any;
}
const books = useQueryWrapper(Book, "...")?.books; // Book[] | undefined
const pages = useQueryWrapper(Page, "...")?.pages; // Page[] | undefined
刚才我问了
请考虑以下代码:
import { ClassConstructor } from "class-transformer";
import { useQuery as useApolloQuery } from "@apollo/client";
class Book {
readonly many = "books" as const;
bookData: any;
}
export const useQueryWrapper = <T>(cls: ClassConstructor<T>, queryString) => {
return useApolloQuery<{ [cls.prototype.many]: T[] }>(queryString);
};
const { data } = useQueryWrapper(Book, "..."); // Book or any other class with a literal `many` prop
TS 将数据识别为以下类型:
const data: {} | undefined
我想让 TS 知道数据有 属性 本书
const data: {
books: Book[];
} | undefined
可能吗?
这可以通过组合 index access types and mapped types (playground):
class Book {
readonly many = "books" as const;
bookData: any;
}
class Page {
readonly many = "pages" as const;
bookData: any;
}
type ManyType = { readonly many: string };
type QueryResult<T extends ManyType> = {
// using K in T["many"] to create an object with a key of value T["many"], e.g. "books", "pages", etc.
[K in T["many"]]: T[];
};
type ClassConstructor<T> = new (...args: any[]) => T;
function useQueryWrapper<T extends ManyType>(
cls: ClassConstructor<T>,
queryString: string
): QueryResult<T> | undefined {
return {} as any;
}
const books = useQueryWrapper(Book, "...")?.books; // Book[] | undefined
const pages = useQueryWrapper(Page, "...")?.pages; // Page[] | undefined