【问题标题】:typescript converting Object.entries reduced derived string array to literal types打字稿转换 Object.entries 将派生字符串数组减少为文字类型
【发布时间】:2022-01-03 16:54:46
【问题描述】:
const program = {
  morgning: ['breakfast', 'mingle'],
  evning: ['mingle', 'eat', 'party']
} as const

const namespaceEvent = Object.entries(program).reduce(
  (acc, [namespace, events]) => [...acc, ...events.map(event => `${namespace}.${event}`)],
  [] as string[]
) // can't do 'as const' here;

type Namespace = typeof namespaceEvent[number] // sees the type as 'string' and not "morgning.breakfast" | "morgning.mingle" | "evning.mingle" | "evning.eat" | "evning.party"

const test: Namespace = 'foo.bar' // would like this to error

console.log(namespaceEvent) // ["morgning.breakfast", "morgning.mingle", "evning.mingle", "evning.eat", "evning.party"] 

我该如何进行这项工作,为什么它不起作用?

【问题讨论】:

标签: javascript typescript


【解决方案1】:

我认为这是解决这个问题的一种方法:

比我想象的要复杂得多,可能有更好的方法!

const program = {
  morgning: ['breakfast', 'mingle'],
  evning: ['mingle', 'eat', 'party']
} as const

type KV = {[K in keyof typeof program]: `${K}.${typeof program[K][number]}`};
type NS = KV[keyof KV];
// type NS = "morgning.breakfast" | "morgning.mingle" | "evning.mingle" | "evning.eat" | "evning.party"

const namespaceEvent = Object.entries(program).reduce(
  (acc, [namespace, events]) => [...acc, ...events.map(event => `${namespace}.${event}`)] as NS[],
  [] as NS[]
) 


const test: NS = 'foo.bar' // ERROR: Type '"foo.bar"' is not assignable to type 'NS'.
const test1: NS = 'morgning.breakfast' // works


console.log(namespaceEvent) // ["morgning.breakfast", "morgning.mingle", "evning.mingle", "evning.eat", "evning.party"] 

查看 TS Playground:https://tsplay.dev/WJRV5W

【讨论】:

  • Here's a version using flatMap。打字是一样的,但实现有点短。
  • 干得好@Aplet123 感谢分享。我倾向于使用reduce,但这更干净
猜你喜欢
  • 1970-01-01
  • 2020-05-08
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 2019-11-12
  • 2020-11-21
  • 2023-02-10
相关资源
最近更新 更多