【问题标题】:How to write types / or use use types for flatten object key in typescript?如何在打字稿中为展平对象键编写类型/或使用使用类型?
【发布时间】:2020-05-29 04:13:42
【问题描述】:

考虑这种情况

interface abc {
  a: { b: string }
}

const test: abc = { a: { b: 'string'} }

test['a.b'] = 'new string' // error type a.b doesnt exists

https://codesandbox.io/s/delicate-night-9u5ps?file=/src/index.ts

如何解决这个错误?如何使用已定义的类型并仍然使用 flatten 键?

PS:我不能像 test.a.b 那样使用它

【问题讨论】:

  • 你是如何展平这个对象的?您链接的沙箱也没有您的代码。
  • 我是手动操作的,因为我只需要一个键。更新了链接

标签: javascript typescript


【解决方案1】:

我们希望 Typescript 在这里做的是将一组键转换为另一组键。它可以通过多种方式做到这一点,例如 Pick:

interface IA {
    a: number;
    b: number;
    c: boolean;
}

const x: Pick<IA, 'a' | 'b'> = {
    a: 1,
    b: 2,
    c: 3, // type error here as we're not picking that property
}

在此示例中,Typescript 能够基于选择某些指定键在键集 ['a', 'b', 'c']['a', 'b'] 之间进行转换。我们还可以扩展对象的键:

type TestExtentionType = IA & { d: number };

const y: TestExtentionType = {
    a: 1,
    b: 2,
    c: true,
    d: 4,
}

为了让 typescript 自动确定您正在寻找的返回类型,我们需要类型系统做的是能够从 key, key 转到 'key.key',或者更一般地说,我们需要 Typescript 的类型系统来连接字符串文字。在我写这篇文章的时候,it doesn't seem to be possible to have typescript do that.

我可以看到接近您需要的唯一选择是使用您的扁平键定义特定类型:

interface abc {
  a: { b: string }
}

interface abcFlattened {
    'a.b': string;
}

const flattenAbc = (x: abc): abcFlattened =>
    // do the flattening

其他选项涉及完全重写您正在做的事情;如果您想以“a.b”的形式获取该键,那么我不知道还有其他方法可以做到这一点。

【讨论】:

  • 感谢您的回答,您认为有解决方法吗?
  • 我只是想在答案中编辑一些有用的东西哈
  • @heypran 希望我能给你一些更好的选择,如果你对一些完整的重写感兴趣,我可以举一些例子
  • 谢谢,我无法重写 atm。 :)
猜你喜欢
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
  • 2021-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
相关资源
最近更新 更多