【问题标题】:Define typescript object shape without index signature定义没有索引签名的打字稿对象形状
【发布时间】:2021-05-30 18:03:45
【问题描述】:

如果这在某种程度上是 TypeScript 中的设计差距,我真的很好奇。 假设我有一个函数,它接受任何满足这个接口的对象

interface Params {
    [key: string]: string | number | boolean | undefined | null;
}

所以key必须是字符串,属性的类型可以是primitive或者void。

如果我现在指定某个方法采用特定接口,而该接口本身就满足 Params 接口,我会收到错误消息,即另一个接口没有索引签名。 所以其他界面可能只是简单的样子。

interface Foo {
    bar: string;
}

我也尝试将签名更改为Record<string, string | number | boolean | undefined | null>,但这也会导致缺少索引签名错误。

然后我的整个代码可能看起来像这样。给一个完整的画面。所以我需要在Object.entries中指定对象的键值类型才能进行某些操作

function specificFunction(obj: Foo) {
  genericFunction(obj);
}

function genericFunction(params: Params) {
  Object.entries(params).forEach(([key, value]) => {
    …
  })
}

编辑: 重要说明,specificFunction 的行为应该保持不变,因为它应该用于缩小允许的接口,因为在这种特殊情况下,只有具有某些属性的对象才被允许确保特定的结果。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    genericFunction 期望类型为 index signature

    Foo默认没有索引签名,因为它是一个接口。

    但是有一个小提示。如果您使用 type 关键字声明 Foo 而不是 interface - 它会起作用。

    为什么?

    因为type默认有索引签名。

    请参阅this 答案。

    所以,接下来的代码将编译:

    interface Params {
        [key: string]: string | number | boolean | undefined | null;
    }
    
    // use type here instead of interface
    type Foo = {
        bar: string;
    }
    
    function specificFunction(obj: Foo) {
      genericFunction(obj);
    }
    
    function genericFunction(params: Params) {
      Object.entries(params).forEach(([key, value]) => {
    
      })
    }
    

    Playground

    更新 2 如果您无法控制 ParamsFoo,则可以使用下一个实用程序类型:

    interface Params {
        [key: string]: string | number | boolean | undefined | null;
    }
    
    interface Foo {
        bar: string;
    }
    
    type Values<T> = T[keyof T]
    
    type MakeIndexed<T> = {
        [P in keyof T]: T[P]
    }
    
    function specificFunction(obj: MakeIndexed<Foo>) {
        genericFunction(obj);
    }
    
    function genericFunction(params: Params) {
        Object.entries(params).forEach(([key, value]) => {
    
        })
    }
    

    【讨论】:

    • 好的,我们假设 Params 和 Foo 都来自库,我无法将其更改为 type。
    • @DaSch 请提供您有问题的所有限制/要求
    • 是的,很抱歉,因为这意味着这看起来仍然不是解决方案,而是一种解决方法。因为现在可以使用接口中未定义的属性调用 specificFunction。所以也许我忘了提,行为应该保持不变。
    • 同意,我更新了MakeIndexed 类型。它适合你吗?
    猜你喜欢
    • 1970-01-01
    • 2018-12-15
    • 2021-11-12
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 1970-01-01
    相关资源
    最近更新 更多