【问题标题】:Typescript Interface with unknown key name具有未知键名的打字稿接口
【发布时间】:2020-12-07 16:02:42
【问题描述】:

我试图在 Typescript 中创建一个接口,该接口同时具有 Unkown 键名和已知键名。像这样的:

interface Data { 
    test: string,
    [key: string]: string,
    foo?: boolean,
}

所以我能够做到这一点:

x: Data = {
  test: "test_string",
  "unknown_key": "value"
}

有人知道我是怎么做到的吗?谢谢。

【问题讨论】:

  • [key: string] 的可能类型必须涵盖所有其他属性的类型,因此在您的情况下为[key: string]: string | boolean | undefined

标签: typescript types interface typing


【解决方案1】:

一种方法是将自定义字段与Record<string, string> 结合起来:

type Data = Record<string, string> & { 
  test: string;
  foo?: boolean;
}

【讨论】:

  • 这个解决方案不是类型安全的,因为你仍然可以使用string 来代替foo
【解决方案2】:

这里有一个例子:


// You can omit `test` property in Data interface since it has a string type
interface Data { 
    [key: string]: string,
    foo?: boolean,
}

// You can use Verify helper instead of Data interface. It is almost the same
type VerifyT<T> = { foo?: boolean } & { [K in keyof T]: K extends "foo" ? unknown : string };

const make = <T extends VerifyT<T>>(t: T) => t;
make({ age: 'sdf', foo: true }) // Ok
make({ age: 'sdf', foo: undefined }) // ok
make({ age: 'sdf', foo: undefined }) // false
make({ age: 'sdf', foo: 'some text' }) // error
make({ age: 'sdf', foo: 1 }) // error
make({ age: 'sdf', foo: [1] }) // error

不用担心函数开销,因为如果你使用 V8 引擎,它将被 99% 内联和优化

所有评分都转到this 答案。

也可以随意将此问题标记为重复问题

【讨论】:

    猜你喜欢
    • 2014-07-17
    • 2021-02-02
    • 2018-12-29
    • 1970-01-01
    • 2021-12-09
    • 2018-05-30
    • 2020-05-09
    • 2017-09-02
    • 1970-01-01
    相关资源
    最近更新 更多