玩了一段时间之后,我想到了以下内容。仍然存在重复,但是至少存在一些交叉检查可以帮助防止错误。这样做的主要问题是它很冗长,很容易忘记一种组合。
type Pair<A,B> = [A,B]
const pair = <A,B>(a: A,b: B): Pair<A,B> => [a,b]
type ShirtYellow = Pair<Formats.Shirt,Shirt.Yellow>
type ShirtOrange = Pair<Formats.Shirt,Shirt.Orange>
type FruitOrange = Pair<Formats.Fruit,Fruit.Orange>
type FruitLemon = Pair<Formats.Fruit,Fruit.Lemon>
const ShirtYellow: ShirtYellow = pair(Formats.Shirt,Shirt.Yellow)
const ShirtOrange: ShirtOrange = pair(Formats.Shirt,Shirt.Orange)
const FruitOrange: FruitOrange = pair(Formats.Fruit,Fruit.Orange)
const FruitLemon: FruitLemon = pair(Formats.Fruit,Fruit.Lemon)
export type Item = ShirtYellow | ShirtOrange | FruitOrange | FruitLemon
export const Item = { ShirtYellow,ShirtOrange,FruitOrange,FruitLemon };
这是我的第二次尝试。这次是基于对象的解决方案。
type AbstractItem<I extends { kind: Formats,type: any }> = I
export type ShirtItem = AbstractItem<{kind: Formats.Shirt,type: Shirt}>
export type FruitItem = AbstractItem<{kind: Formats.Fruit,type: Fruit}>
export type Item = AbstractItem<ShirtItem | FruitItem>
export const isShirt = (i: Item): i is ShirtItem => i.kind === Formats.Shirt
export const isFruit = (i: Item): i is FruitItem => i.kind === Formats.Fruit
export const getShirt = (i: Item): Shirt|null => isShirt(i) ? i.type : null
export const getFruit = (i: Item): Fruit|null => isFruit(i) ? i.type : null
,
我认为我们不应该专注于枚举之类的原始值类型。适当的记录或课程可以做您想要的。使用TypeScript,您可以构建"discriminated unions",即可以用一个字段(“标记”)区分的一类类型:
export enum ShirtOptions {
Yellow = 'yellow',Orange = 'orange',}
export enum FruitOptions {
Orange = 'orange',Lemon = 'lemon',}
interface Shirt {
kind: 'shirt';
options: ShirtOptions;
}
interface Fruit {
kind: 'fruit';
options: FruitOptions; // Can have a different name
}
type Format = Shirt | Fruit;
function handler(f: Format) {
switch (f.kind) {
case "shirt": return doShirtStuff();
case "fruit": return doFruitStuff();
}
}
TypeScript会对switch语句进行详尽的检查,并告诉您是否无法处理所有情况(有关详细信息,请参见链接)。
本文链接:https://www.f2er.com/2115987.html