私がやろうとしていることは不可能のようですが、それが本当に可能であることを願っています。
基本的に、私は2つのインターフェースを持っていますが、両方の組み合わせとして単一の関数パラメーターに注釈を付けたいと思います。
interface ClientRequest {
userId: number
sessionKey: string
}
interface Coords {
lat: number
long: number
}
そして、関数で、私はこのようなことをしたいです:
function(data: ClientRequest&Coords) { ... }
そのため、「データ」オブジェクトには、両方のタイプのすべてのメンバーを含めることができます。
「型のメンバーの結合」の下にある spec preview で参照されているものを見ましたが、これはまだ組み込まれていないようです。
それが不可能な場合、私の解決策は次のようになります。
interface ClientRequest<T> {
userId: number
sessionKey: string
data?: T
}
function(data: ClientRequest<Coords>) { ... }
これはこの場合はうまくいきますが、私が望むほど動的ではありません。アノテーション自体で複数の(2+)タイプを組み合わせることができるようになりたいです。
function(data: TypeA&TypeB&TypeC) { ... }
従来の解決策は、これらの型を拡張する型を定義することだと思いますが、柔軟性は低いようです。タイプを追加する場合は、次のいずれかを行う必要があります
TypeScriptの専門家は私を正しい方向に向けようとしていますか?
あなたの質問に対する具体的な回答は次のとおりです。いいえ、結合または拡張されたタイプを示す単一のインライン注釈はありません。
解決しようとしている問題のベストプラクティスは、他の2つを拡張する3番目のタイプを作成することです。
interface IClientRequestAndCoords extends IClientRequest, ICoords {}
function(data: IClientRequestAndCoords)
[〜#〜]更新[〜#〜] 2018-10-30
TypeScriptに型の交差があります。だからあなたは今簡単に行うことができます:
interface ClientRequest {
userId: number
sessionKey: string
}
interface Coords {
lat: number
long: number
}
function log(data: ClientRequest & Coords) {
console.log(
data.userId,
data.sessionKey,
data.lat,
data.long
);
}
インターフェースの回答は、2つの構造を組み合わせる上品な方法ですが、注釈の一部として型を組み合わせることが可能かどうかを知りたいと述べました。
私はあなたの質問に関連するいくつかの機能のいくつかの説明を提供しましたが、最初に私はあなたがあなたのようにICoords
インターフェースを作成する必要があると思うのであなたがインターフェースソリューションから延期されたら質問はクラスのように見えます)-簡単に休める-インターフェースもクラスを拡張できるため
// Interface extending an interface and a class
interface IClientRequestAndCoords extends IClientRequest, Coords {}
同じ名前とタイプである限り、インターフェースはプロパティをマージします。 (たとえば、両方がプロパティx: string
を宣言した場合。
ここに、他の注釈機能についてのメモがあります。
あなたが読んだかもしれない仕様は、次のようなunionタイプです:
var x: IClientRequest | Coords;
しかし、これはx
がどちらか一方であることを保証するだけであり、2つの組み合わせではありません。マージされた型IClientRequest & Coords
の構文は、私が知る限り、ロードマップにはありません。
function go(data: IClientRequest | Coords) {
var a = data[0]; // IClientRequest
var b = data[1]; // Coords
}
// Allowed (even though it doesn't supply Coords data
go(myClientRequest);
// Allowed (even though it doesn't supply IClientRequest data
go (myCoords);
これも現在のリリースには含まれていませんが、後でリリースされます。
あなたが見たかもしれない仕様のもう一つの可能な部分はタプル型です:
var x: [IClientRequest, Coords];
ただし、これにより、データの形状が構造体から配列のようなものに変わり、要素0
はIClientRequest
で、要素1
はCoords
になります。
function go(data: [IClientRequest, Coords]) {
var a = data[0]; // ClientRequest
var b = data[1]; // Coords
}
go([myClientRequest, myCoords]);
最後に、本当にマージされたインターフェースを作成したくない場合は、uber-annotationを使用できます。
function go(data: { userId:number; sessionKey: string; x: number; y: number; } ) {
}
「型のメンバーの結合」の下にある spec preview で参照されているものを見つけましたが、これはまだ組み込まれていないようです。
intersection
タイプ(union
ではない)にもっと興味があると思います。違いは、渡されたオブジェクトがプロパティのallをサポートする必要があり、one ofをサポートしない必要があることです。
Githubの問題: https://github.com/Microsoft/TypeScript/issues/1256#issuecomment-64533287
interface ClientRequest {
userId: number
sessionKey: string
}
interface Coords {
lat: number
long: number
}
type Combined = ClientRequest & Coords;
次に、次のようにデータを定義できます。
let myData = Object.assign({},
<ClientRequest> {
userId: 10,
sessionKey: "gjk23h872ty3h82g2ghfp928ge"
},
<Coords> {
lat: -23,
long: 52
}
);
最後に、関数を呼び出します。
function myFunc(data: Combined) { ... }
myFunc(myData);
これを達成するさらに多くの方法については、この他の質問を参照してください:
私はこれを行う必要があり、次の解決策が私のために働きました:
type MyFunction = () => void
interface MyFunctionWithProps extends MyFunction {
prop1: string,
prop2: number
}
// compiles fine
const MyMashup: MyFunctionWithProps = Object.assign(
() => {},
{
prop1: 'hello',
prop2: 1234
}
)