2017-10-27 2 views
0

私は活字体にいくつかのコードを書いた:Part <T>を満たすためにジェネリック 'T'を返すことができないのはなぜですか?

type Point = { 
    x: number; 
    y: number; 
}; 
function getThing<T extends Point>(p: T): Partial<T> { 
    // More interesting code elided 
    return { x: 10 }; 
} 

をこれがエラーを生成します。

Type '{ x: 10; }' is not assignable to type 'Partial<T>'

これはバグのように思える - { x: 10 }は明らかにPartial<Point>です。ここで間違っているタイプスクリプトは何ですか?これをどうやって解決するのですか?

答えて

1

汎用関数を書くことについて考えるとき、発信者は、型パラメータ

あなたがgetThingのために提供してきました契約を選択します

を覚えておくべき重要なルールが...あります

function getThing<T extends Point>(p: T): Partial<T> 

...はこのような法的呼び出しを意味します。はサブタイプPointです。

const p: Partial<Point3D> = getThing<Point3D>({x: 1, y: 2, z: 3}); 

もちろん、{ x: 10 }となります。Partial<Point3D>です。

サブタイプの機能は、追加のプロパティの追加にのみ適用されるのではありません。サブタイプには、プロパティのドメインのより限定されたセットを選択することが含まれます。あなたが書くとき

type UnitPoint = { x: 0 | 1, y: 0 | 1 }; 

const p: UnitPoint = getThing<UnitPoint>({ x: 0, y: 1}); 

p.xない法的UnitPointある値10を、持っている:あなたは、このようなタイプが持つかもしれません。

このような状況におかれた場合、返品タイプは実際には一般的ではありません。です。より正確な関数シグネチャはなぜ誰かが汎用シグニチャー `関数getThing 希望

function getThing<T extends Point>(p: T): Partial<Point> { 

+0

なり(P:T):部分;'コンクリート '関数getThing(P:ポイント)へ。部分; '?リテラルの余分なプロパティチェック? – jcalz

+0

'(x:T、y:T)'のようなものを書くかもしれません。シングル引数バージョンはあまり意味がありませんが、実際にジェネリックが必要ない人たちを説得するのは難しい場合もあります –

関連する問題