这是一些带有条件类型的代码
class A {
public a: number;
}
class B {
public b: number;
}
type DataType = "a" | "b";
type TData<T extends DataType> =
T extends "a" ? A :
T extends "b" ? B :
never;
现在,我想使用条件类型作为从函数参数到其返回类型的链接。我试图以不同的方式实现这一目标,但没有结果:
function GetData<T extends DataType>(dataType: T): TData<T> {
if (dataType == "a")
return new A();
else if (dataType == "b")
return new B();
}
正确的语法是什么?可以使用TypeScript 2.8吗?
更新
已经有一个opened issue on github涵盖了我的示例。 因此,目前的答案是“不,但将来可能会出现。”
答案 0 :(得分:3)
您可以在此处使用函数重载:
function GetData(dataType: "a"): A;
function GetData(dataType: "b"): B;
function GetData(dataType: DataType): A | B {
if (dataType === "a")
return new A();
else if (dataType === "b")
return new B();
}
const f = GetData('a'); // Inferred A
const g = GetData('b'); // Inferred B
答案 1 :(得分:0)
三元运算符在泛型类型中确实不能很好地发挥作用:
type TriviallyA<T extends DataType> =
T extends any ? A : A;
function GetData<T extends 'a' = 'a'>(dataType: T): TriviallyA<T> {
return new A(); // Error: Type 'A' is not assignable to type 'TriviallyA<T>'
}
但是泛型确实可以很好地与属性查找配合使用,因此您可以定义一个接口以将字符串映射到特定类型,然后可以使用keyof
和属性查找来充当TData
:
interface DataTypeMapping {
a: A;
b: B;
}
type DataType = keyof DataTypeMapping;
type TData<T extends DataType> = DataTypeMapping[T];
function GetData<T extends DataType>(dataType: T): TData<T> {
// now expected return type is A | B so this is valid!
if (dataType === 'a') {
return new A();
} else if (dataType === 'b') {
return new B();
}
}