你能声明一个允许打字稿中未知属性的对象文字类型吗?

Luc*_*cas 9 generics object-literal typescript typescript2.0

基本上我想确保一个对象参数包含所有必需的属性,但可以包含它想要的任何其他属性.例如:

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

foo({ baz: 1, other: 2 });
Run Code Online (Sandbox Code Playgroud)

但这会导致:

Object literal may only specify known properties, and 'other' does not exist in type '{ baz: number; }'.
Run Code Online (Sandbox Code Playgroud)

Luc*_*cas 17

好吧,我讨厌回答我自己的问题,但其他答案激发了我的一些思考......这有效:

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

foo({baz: 1, other: 2});
Run Code Online (Sandbox Code Playgroud)

  • 看起来您已经对其进行了设置,因此该函数采用类型参数,但您没有为其提供类型参数。你介意解释一下你在这里做什么吗?谢谢。 (2认同)
  • 他让 TS 根据传递给 bar 参数的值自动推断类型参数。 (2认同)

Hoa*_*iep 13

是的你可以.试试这个:

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

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

foo({ baz: 1, other: 2 });
Run Code Online (Sandbox Code Playgroud)

  • 我最初是这么想的,但想要内联......(出于某种原因,我使用括号而不是方括号搞砸了 [key: string] 部分)...... (2认同)
  • 您不必使用“any”,您只需确保包含“|”即可。number`(在本例中),否则您将在“baz: number;”上收到 TS 错误。或者你可以使用“未知” (2认同)

Mar*_*oha 9

如果你想允许整个对象具有未知属性,你可以使用Record

function doStuff(payload: Record<string|number, unknown>): Record<string|number, unknown> {
  return { anyProp: 'anyValue' }
}

Run Code Online (Sandbox Code Playgroud)


Tad*_*sen 6

如果已知字段来自泛型类型,则允许使用通配符的方法是 with T & {[key: string]: unknown},任何已知字段都必须符合类型的约束,并且允许其他字段(并考虑为 type 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
Run Code Online (Sandbox Code Playgroud)

然后,如果您有通用类型T,则可以允许通配符字段WithWildCards<T>