我正在尝试编写代码,该代码将与具有type
属性的泛型区分联合一起工作。
比如说,我有很多受歧视的工会,比如:
interface IFoo {
type: "foo";
foo: number;
}
interface IBar {
type: "bar";
bar: number;
}
interface IBaz {
type: "baz";
baz: number;
}
type IObject = IFoo | IBar | IBaz;
我解决的第一个任务是确定类型属性的可能值:
declare let _object: IObject;
type ObjectType = typeof _object.type;
(顺便问一下,有没有一种方法可以不用额外申报就可以做到这一点?)
我需要声明要使用的泛型类型,如:
Case<IObject, "foo"> // = IFoo
Case<IObject, "bar"> // = IBar
所以我可以声明:
function filter<Type extends ObjectType>(
objects: IObject[],
type: Type,
): Case<IObject, type>[] {
return objects.filter((o) => o.type == type);
}
这可能吗?
最佳答案
是的,有可能
interface IFoo {
type: "foo";
foo: number;
}
interface IBar {
type: "bar";
bar: number;
}
interface IBaz {
type: "baz";
baz: number;
}
type IObject = IFoo | IBar | IBaz;
type TypeSwitch<N extends string, T extends { type: N }> =
{ [n in N]: T extends { type: n } ? T : never };
type Case<T extends { type: string }, N extends T['type']> =
TypeSwitch<T['type'], T>[N];
type F = Case<IObject, "foo">; // = IFoo
type B = Case<IObject, "bar">; // = IBar
此外,您可以使用“索引类型查询”类型运算符来引用属性的类型(实际上与使用
[]
的属性访问相同的语法,只对类型进行操作)。type ObjectType = IObject['type'];
最后,在
filter
中使用上面所有给出的过滤数组元素的类型:function filter<Type extends ObjectType>(
objects: IObject[],
type: Type,
): Case<IObject, Type>[] {
return objects.filter((o) => o.type == type);
}
let o: IObject[];
const a = filter(o, 'bar'); // inferred as const a: IBar[]
关于typescript - 销毁歧视性工会,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50263575/