如何从类属性(在将类作为参数传递后)获取计算属性名称的文字类型? [英] How to get a literal type from a class property (after passing the class as argument) for a computed property name?

查看:29
本文介绍了如何从类属性(在将类作为参数传递后)获取计算属性名称的文字类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

刚才我问了 这个问题 现在我有一个后续问题 :)

a moment ago I asked this question and now I have a follow up one :)

请考虑以下代码:

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 将数据识别为以下类型:

TS recognizes data as the following type:

const data: {} | undefined

我想让 TS 知道 data 有一个属性书

I'd like TS to know that data has a property books

const data: {
    books: Book[];
} | undefined

有可能吗?

推荐答案

这可以通过 索引访问类型游乐场):

This is possible with a combination of 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

这篇关于如何从类属性(在将类作为参数传递后)获取计算属性名称的文字类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆