没有源代码很难解释这一点,所以请看下面的代码片段:
type Type1 = { num1: number; str1: string };
type Type2 = { num2: number; str2: string };
type Type3 = { num3: number; str3: string };
type Type4 = { num4: number; str4: string };
enum MyEnum {
ONE,
TWO,
THREE,
FOUR,
}
type MyTypes<T> = T extends MyEnum.ONE
? Type1
: T extends MyEnum.TWO
? Type2
: T extends MyEnum.THREE
? Type3
: T extends MyEnum.FOUR
? Type4
: never;
const urls = {
[MyEnum.ONE]: 'http://one.com',
[MyEnum.TWO]: 'http://two.com',
[MyEnum.THREE]: 'http://three.com',
[MyEnum.FOUR]: 'http://four.com',
};
const fetchData = (_url: string): unknown => ({
// ...
});
export const myFun = <T extends MyEnum>(type: T) => {
const data = fetchData(urls[type]);
return { data: data as MyTypes<T> };
};
const one = myFun<MyEnum.ONE>(MyEnum.ONE);
const two = myFun<MyEnum.TWO>(MyEnum.TWO);
const three = myFun<MyEnum.THREE>(MyEnum.THREE);
const four = myFun<MyEnum.FOUR>(MyEnum.FOUR);
myFun()
在这里接收相同的两次:
- 作为泛型类型,静态用于确定返回的
data
的类型。 - 作为一个参数,用于在运行时选择正确的
url
注意这就像一个符咒。甚至写一些像myFun<MyEnum.ONE>(MyEnum.TWO)
是不允许的,因为我不允许传递一个不同的类型的泛型和参数。返回的类型是正确的类型和myFun()
的工作,因为我需要。
问题是什么?我发现它很难看,我想使用myFun()
只传递一次类型,方法如下:
const a = myFun<MyEnum.ONE>(); // Option 1
const b = myFun(MyEnum.ONE); // Option 2
有可能吗?
我试过:
- 选项1(仅使用泛型),但在运行时无法选择正确的
url
。 - 选项2(只使用参数)作为
const myFun = (type: MyEnum) => {...}
,但是我不能为返回的data
分配正确的类型。 - 注意**:任何其他简化的建议都是受欢迎的。例如,
MyTypes<T>
的定义看起来很难看,但我不知道其他的方法。
- 注意**:任何其他简化的建议都是受欢迎的。例如,
1条答案
按热度按时间8qgya5xd1#
多亏了@Tobias S,我发现TypeScript在调用函数时不需要提供泛型,因为它是从参数中推导出来的。所以可以定义
myFun()
如下:但你可以把它当作
TypeScript将从泛型中推断
data
类型,泛型是从作为参数接收的值中推断出来的(因为它与泛型提供的相同)。