- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想扁平化对象并将返回值转换为一种类型。
例如:
const myObject = {
names: {
title: 'red',
subtitle: 'green'
},
}
const returned = [...Object.values(flatten(myObject))] as const
// returns ['red', 'green']
type Type = typeof returned[number]
返回的变量现在是 ['red', 'green']
类型应该是'red | 'green',但现在是一个字符串数组,因为返回的 typeof 是 string[]。我想使用这种类型为我的组件键入 prop:
<Component name="red" /> //is correct, but
<Component name=`something different than "red" or "green"` /> //is incorrect.
扁平化功能:
type FlattenedObject = { [x: string]: string }
export const flattenDaisyChain = (obj: any): FlattenedObject => {
const result: FlattenedObject = {}
const transform = (wrapper: FlattenedObject | string, p?: string) => {
switch (typeof wrapper) {
case 'object':
p = p ? p + '.' : ''
for (const item in wrapper) {
transform(wrapper[item], p + item)
}
break
default:
if (p) {
result[p] = wrapper
}
break
}
}
transform(obj)
return result
}
最佳答案
首先,如果你想让编译器意识到 Type
是 "red"| "green"
相对于 string
,我们必须确保 myObjct
的类型包括这些 literal types .最简单的方法是使用 const
assertion :
const myObject = {
names: {
title: 'red',
subtitle: 'green'
},
} as const;
接下来,您的 flatten()
函数的类型在 TypeScript 4.1+ 中几乎无法表示。我可能会这样写,使用 similar question 的答案:
type Flatten<T extends object> = object extends T ? object : {
[K in keyof T]-?: (x: NonNullable<T[K]> extends infer V ? V extends object ?
V extends readonly any[] ? Pick<T, K> : Flatten<V> extends infer FV ? ({
[P in keyof FV as `${Extract<K, string | number>}.${Extract<P, string | number>}`]:
FV[P] }) : never : Pick<T, K> : never
) => void } extends Record<keyof T, (y: infer O) => void> ?
O extends infer U ? { [K in keyof O]: O[K] } : never : never
const flatten = <T extends object>(obj: T): Flatten<T> => { /* impl */ }
它使用 recursive conditional types , template literal types , 和 key remapping in mapped types递归遍历所有属性并将键与 .
连接在一起。我不知道这个特定类型的函数是否适用于 flatten()
的所有用例,我不敢假装它没有潜伏在其中的恶魔。
如果我使用那个签名,并用上面的 const
-asserted myObject
调用 flatten(myObject)
,你会得到这个:
const flattenedMyObject = flatten(myObject);
/* const flattenedMyObject: {
readonly "names.title": "red";
readonly "names.subtitle": "green";
} */
万岁!这足以让 Type
成为 "red"| “绿色”
:
const returned = [...Object.values(flatten(myObject))] as const
type Type = typeof returned[number] // "red" | "green"
也万岁。
我想如果你真的不关心跟踪键名,你可以通过返回 string
index signature 来大大简化 flatten()
类型签名。 :
type DeepValueOf<T> = object extends T ? object :
T extends object ? DeepValueOf<
T[Extract<keyof T, T extends readonly any[] ? number : unknown>]
> : T
const flatten = <T extends object>(obj: T): { [k: string]: DeepValueOf<T> } => {
/* impl */ }
产生
const flattenedMyObject = flatten(myObject);
/* const flattenedMyObject: {
[k: string]: "green" | "red";
} */
最终
const returned = [...Object.values(flatten(myObject))] as const
type Type = typeof returned[number] // "red" | "green"
我对 DeepValueOf
的担心不如对 Flatten
的担心,但如果没有一些边缘情况,我会感到惊讶。因此,在任何类型的生产代码中使用它之前,您都需要进行真正的测试。
关于typescript - 在 Typescript 中使用自定义键展平对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66614528/
您好,我有一个使用 JSON.Stringify 输出到此的对象 {"0":["test1","ttttt","","","","","","","",""],"1":["test2","ghjgjh
我有以下数据框,它是执行 groupby + 聚合总和的结果: df.groupby(['id', 'category']).agg([pd.Series.sum])
我有一个 3D 三角形带(见插图)。三角形不在一个平面内。 我想展平三角形带,使所有三角形都位于第一个三角形的平面内。 计划是围绕与第一个三角形的连接边旋转第二个三角形,使其与第一个三角形在同一平面内
简单地说,我正在寻找可在 iOS 上使用的与 NSBezierPath 的 -bezierPathByFlatteningPath 等效的方法。这对我来说是直接处理 CGPath 的函数还是 UIBe
假设我有以下 JToken: @"{ ""data"": [ { ""company"": { ""ID"": ""12
如果我在多个分支中处理单个功能,我会使用 git pull branch1 branch2 branch3 将所有更改 pull 入我的主分支。但是,每个分支的所有提交日志也会被复制。如何将提交日志扁
这个问题在这里已经有了答案: How do I make a flat list out of a list of lists? (33 个答案) 关闭6年前。 假设我们有一个返回列表(或有限迭代器)
给定如下模式: root |-- first_name: string |-- last_name: string |-- degrees: array | |-- element: struc
我有一个包含多个列的表,其中一些列是相同长度的数组。我想解除它们的嵌套,以获得包含来自不同行中的数组的值的结果。 所以有这样一张 table : 我想去: 这是其中一个数组列的工作方式: WITH d
我最近买了一台 RICOH THETA S,用于在 360 vr 中录制足球比赛。 我想使用 ffmpeg 将我用我的相机录制的鱼眼电影展平,这可能吗? enter image description
这是我的 question 的后续.是否可以将表格展平为如下所示,而不是数据透视表: data = {'year': ['2016', '2016', '2015', '2014', '2013'],
我目前正在将我的 jruby/java2d 图形绘制/布局应用程序移植到 macruby/cocoa。因此我需要获取开放的 NSBezierPath 与封闭的 NSBezierPath 的交点。 在
是否有一种简单的方法来展平一组 try 以给出尝试值的成功或失败? 例如: def map(l:List[Int]) = l map { case 4 => Failure(new Excepti
我有一个包含数百万行的“服务”表。每行对应于工作人员在给定日期和时间间隔内提供的服务(每行都有一个唯一的 ID)。在某些情况下,工作人员可能会在重叠的时间范围内提供服务。我需要编写一个查询来合并重叠的
我在使用Elastic Search(ES)检索JSON对象时遇到问题。现在,当我尝试使用下面的请求正文从ES查询一些数据时, "_source": [ "data.id", "dat
我有一个订单流(来源是订单列表)。每个订单都有一个 Customer 和一个 OrderLine 列表。 我想要实现的是拥有一个以客户为键的 map ,以及属于该客户的所有订单行,在一个简单的列表中作
给定一个如下所示的复杂对象: case class Complex ( id: Long, name: String, nested: Seq[Complex] ) 实际上,这可能会变成这
我很好奇你如何将数组 Promise 映射的结果展平。我有一个函数 Promise.maps 一组值,它们本身就是 promise (需要解析)并返回一个数组。所以,我得到类似的结果: [ [1, 2
我是 CouchDB 的新手,我只是想评估它在常见任务中的实用性。其中一项任务是生成报告。我的问题是:如果我有这样的文档结构: { "_id": "29763f342ab34fd7b579fd4
假设我们有这样的 map : %{"a": %{"b": 2, "c":5}, "d": 1} 有没有类似this function的东西(js回答同一问题)内置elixr? 最终结果应该是: %{"
我是一名优秀的程序员,十分优秀!