正在从泛型类型中提取类型或接口名称作为Typescript中的字符串



我对TypeScript还很陌生,所以请耐心等待。

基本上,我试图从我的泛型类型中提取类型/接口的名称。这里有一些代码可以解释:

interface Account {
id: string;
firstName: string;
}
// I know this is completely wrong but just wanted to show what my idea is.
// I just want a function to be able to return the name of my interface as a string.
const returnNameOfInterface = <T>() => {
return nameOf T;
}
const name = returnNameOfInterface<Account>(); // This would return 'Account'

显然,上面的代码不正确,但我只想举一个例子说明我的最终目标是什么

编辑

这里有一个例子,我希望能更好地解释我正在努力实现的目标:

interface Account {
id: string;
accountName: string;
}
interface AccountInput {
id: string | null | undefined;
accountName: string | null | undefined;
}
interface Contact {
id: string;
firstName: string;
}
interface ContactInput {
id: string | null | undefined;
firstName: string | null | undefined;
}

const returnFieldsFromEntity = (entity: string) => {
if (entity === 'Account') {
return { id: undefined, accountName: undefined, accountField1: undefined, accountField2: undefined }
}
if (entity === 'Contact') {
return { id: undefined, firstName: undefined, lastName: undefined }
}
}
const accountInput = {
id: '1',
accountName: 'Amazon',
}
const contactInput = {
id: '1',
firstName: 'Sam',
}
const allDataUsingNameOfType = <T, P = any>(data: P): T => {
const fields = returnFieldsFromEntity(nameOf T); // nameOf T would return 'Account' or 'Contact'
const mergeData = { ...fields, ...data };
return mergeData;
}
const allDataUsingEntityParam = <T, P = any>(data: P, entity: string): T => {
const fields = returnFieldsFromEntity(entity); // nameOf T would return 'Account' or 'Contact'
const mergeData = { ...fields, ...data };
return mergeData;
}

const getAllAccountData = allDataUsingNameOfType<Account, AccountInput> (accountInput); // This would return { id: '1', accountName: 'Amazon, accountField1: undefined, accountField2: undefined } which would be a typeof Account
const getAllContactData = allDataUsingNameOfType<Contact, ContactInput> (contactInput); // This would return { id: '1', firstName: 'Sam', lastName: undefined } which would be a typeof Contact
// This would use a separate parameter in my function to know what my entity is. This seems redundant when the interface name is the same as the entity name.
const getAllAccountData1 = allDataUsingEntityParam<Account, AccountInput>(accountInput, 'Account'); // This would return { id: '1', accountName: 'Amazon, accountField1: undefined, accountField2: undefined } which would be a typeof Account
const getAllContactData1 = allDataUsingEntityParam<Contact, ContactInput>(contactInput, 'Contact'); // This would return { id: '1', firstName: 'Sam', lastName: undefined } which would be a typeof Contact

不能这样做有两个原因。

  1. 运行时不存在接口。编译后,您的代码只是returnNameOfInterface(),因此接口的任何标识符都将完全消失。这意味着编译后的javascript不可能从传入的类型中获得任何信息。

  2. Typescript使用基于值的类型,而不是基于标识的类型。这意味着,如果两个界面的形状相同,则界面也相同。因此,您希望以下内容能得到什么回报?

interface Account {
id: string;
firstName: string;
}
returnNameOfInterface<{
id: string
firstName: string
}>();

关键是,获取接口的名称并不像您想象的那样简单。


无论你想做什么,我保证有更好的方法。

最新更新