web-dev-qa-db-ja.com

typescriptで未知のプロパティを許可するオブジェクトリテラルタイプを宣言できますか?

基本的に、オブジェクト引数に必要なすべてのプロパティが含まれていることを確認したいのですが、必要な他のプロパティを含めることができます。例えば:

function foo(bar: { baz: number }) : number {
    return bar.baz;
}

foo({ baz: 1, other: 2 });

しかし、これは次の結果になります。

Object literal may only specify known properties, and 'other' does not exist in type '{ baz: number; }'.
10
Lucas

まあ、私は自分の質問に答えるのは嫌いですが、他の答えは少し考えを刺激しました...これはうまくいきます:

function foo<T extends { baz: number }>(bar: T): void {
    console.log(bar.baz);
}

foo({baz: 1, other: 2});
3
Lucas

はい、できます。これを試して:

interface IBaz {
    baz: number;
    [key: string]: any;
}

function foo(bar: IBaz) : number {
    return bar.baz;
}

foo({ baz: 1, other: 2 });
12
Hoang Hiep

これは、関数呼び出しの前にオブジェクトを定義することで最も簡単に実現できます。

function foo(bar: { baz: number }) : number {
    return bar.baz;
}

const obj = { baz: 1, other: 2 };

foo(obj);
2
Steven Barnett

既知のフィールドがジェネリック型からのものである場合、ワイルドカードを許可する方法はT & {[key: string]: unknown}を使用することです。既知のフィールドはすべて、型の制約に適合している必要があり、他のフィールドは許可されます(タイプunknownと見なされます)。

サンプルは次のとおりです。

type WithWildcards<T> = T & { [key: string]: unknown };

function test(foo: WithWildcards<{baz: number}>) {}

test({ baz: 1 }); // works
test({ baz: 1, other: 4 }); // works
test({ baz: '', other: 4 }); // fails since baz isn't a number

次に、ジェネリック型Tがある場合は、WithWildCards<T>でワイルドカードフィールドを許可できます。