2017-07-12 7 views
4

私のアプリにはいくつかのタイプがあり、共通する属性はほとんどありません。私は共通の属性を分離型に抽象化しました。ここでは、共通の基本型を持つ型を受け入れる関数を記述したいと思います。flowtypeを使って関数の引数をサブタイプ化する

この数行は言葉よりもずっと優れた問題について説明します。

type Box = { 
    width: number, 
    height: number, 
} 

// is like Box + it has position 
type PositionedBox = Box & { 
    type: 'positionedBox', 
    left: number, 
    top: number, 
} 

// is like Box + it has colo 
type ColorBox = Box & { 
    type: 'colorBox', 
    color: string, 
} 

const logSize = (obj: Box) => { 
    console.log({ w: obj.width, h: obj.height }); 
}; 

const logPosition = (obj: PositionedBox) => { 
    console.log({ l: obj.left, t: obj.top }); 
}; 

const logColor = (obj: ColorBox) => { 
    console.log({color: obj.color}); 
}; 

// this function should accept any Box like type 
const logBox = (obj: Box) => { 
    logBox(obj); 
    // $ERROR - obj Box has no type property 
    // (make sense at some point, but how to avoid it?) 
    if (obj.type === 'colorBox') logColor(obj); 
    if (obj.type === 'positionedBox') logPosition(obj); 
} 

質問です:logBox()関数宣言がflowtypeチェックを通過するためにのように見える必要がありますどのように。

+0

値を比較する前に 'type'プロパティの存在をテストできませんか?あるいは単純な '' Box''型のプロパティをジェネリック型に追加しても良いでしょうか? – Kaddath

+0

@Kaddath 'type' propの存在を確認するのはあまり変わっていません。私はまだオブジェクトタイプにプロパティが見つかりません。 ジェネリック型で遊んでいましたが、動作させることができませんでした。これはどうですか? – michaltaberski

+0

タイプをBoxに追加して問題を解決していないのですか? – Kaddath

答えて

1

Boxのサブタイプであるため、{width: 5, height: 5, type: 'colorBox'}logBox関数に渡すことが何も停止しないため、これらのエラーは正当です。 Boxのサブタイプを本当に受け入れる場合は、結果に対処する必要があります。これは、typeフィールドをチェックすると、他のプロパティに関する情報が得られません。

Boxの特定のサブタイプのみを許可する場合は、disjoint unionが必要です。私はBoxBaseBoxに改名し、2つの特殊なボックスの和集合である別のBoxタイプを追加しました。この例は合格します。

type BaseBox = { 
    width: number, 
    height: number, 
} 

// is like Box + it has position 
type PositionedBox = BaseBox & { 
    type: 'positionedBox', 
    left: number, 
    top: number, 
} 

// is like Box + it has colo 
type ColorBox = BaseBox & { 
    type: 'colorBox', 
    color: string, 
} 

type Box = PositionedBox | ColorBox; 

const logSize = (obj: Box) => { 
    console.log({ w: obj.width, h: obj.height }); 
}; 

const logPosition = (obj: PositionedBox) => { 
    console.log({ l: obj.left, t: obj.top }); 
}; 

const logColor = (obj: ColorBox) => { 
    console.log({color: obj.color}); 
}; 

// this function should accept any Box like type 
const logBox = (obj: Box) => { 
    logBox(obj); 
    // $ERROR - obj Box has no type property 
    // (make sense at some point, but how to avoid it?) 
    if (obj.type === 'colorBox') logColor(obj); 
    if (obj.type === 'positionedBox') logPosition(obj); 
} 
関連する問題