- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想定义一个 TS 函数来将对象转置为数组,例如:
const original = {
value: [1, 2, 3],
label: ["one", "two", "three"]
}
const transposed = [
{value: 1, label: "one"},
{value: 2, label: "two"},
{value: 3, label: "three"}
]
然后我想声明一个接收
original
的函数和输出
transposed
反之亦然,例如:
function tranpose(original: T): Array<T> // Incorrect, the output should be a transposed version of the object.
如何定义对象的转置版本并正确声明函数?
最佳答案
呵呵,你要Transpose<Transpose<T>>
产生类似 T
的东西, 对?而且我假设,虽然在问题中没有明确说明,但您希望它适用于包含对象或数组的任意对象或数组,而不是专门“具有 value
和 label
属性的东西,其中包含数组”。
这在概念上很容易,但在处理对象与数组时事情会变得棘手。即使 mapped types should produce array/tuples from array/tuples ,有些陷阱编译器没有意识到它正在映射数组/元组,直到为时已晚,并且您的映射类型充满了可怕的数组方法,例如 "length" | "push" | "pop" |...
.我假设你的实现也会有一些毛毛病,但我担心这里的类型,而不是实现。
这是我的版本,除了 IntelliSense 显示相同类型的联合(例如 type Foo = "a" | "a" | "a"
您希望看到 type Foo = "a"
)的一些奇怪之外,它可以工作,幸运的是它不会影响类型的行为方式:
type Transpose<T> =
T[Extract<keyof T, T extends readonly any[] ? number : unknown>] extends
infer V ? { [K in keyof V]: { [L in keyof T]:
K extends keyof T[L] ? T[L][K] : undefined } } : never;
declare function transpose<T>(t: T): Transpose<T>;
解释是我们正在遍历
T
的值/元素类型。找出输出类型的键应该是什么。那应该是
T[keyof T]
但我们需要做
T[Extract<keyof T, ...]
以确保数组不会把事情搞砸。然后我们大多只是转
T[K][L]
进入
T[L][K]
在此过程中进行一些类型检查。
const
assertion或者类似的东西,如果你想让编译器跟踪哪些值在哪些键上:
const original = {
value: [1, 2, 3],
label: ["one", "two", "three"]
} as const
/* const original: {
readonly value: readonly [1, 2, 3];
readonly label: readonly ["one", "two", "three"];
} */
现在我们将转置它:
const transposed = transpose(original);
/* readonly [{
readonly value: 1;
readonly label: "one";
}, {
readonly value: 2;
readonly label: "two";
}, {
readonly value: 3;
readonly label: "three";
}]
*/
transposed.forEach(v => v.label) // transposed is seen as an array
transposed[1].label // known to be "two"
看起来挺好的。如果您在
transposed
上使用 IntelliSense你会看到它是三个相同类型的联合,但是🤷♂️。 (这是 TypeScript 的一个已知设计限制;参见
microsoft/TypeScript#16582 。可以强制编译器积极减少联合,如
here 所示,但这并不是这个问题的真正重点,所以我离题了。)输出类型被视为一个元组,因此它具有我假设您想要的所有数组方法。
const reOriginal = transpose(transposed);
/* const reOriginal: {
readonly value: readonly [1, 2, 3];
readonly label: readonly ["one", "two", "three"];
} */
reOriginal.label.map(x => x + "!"); // reOriginal.label is seen as an array
再次,看起来不错。
reOriginal
的类型是(模 IntelliSense)与
original
的类型相同.万岁!
关于typescript - 如何声明类型的 "transposed"版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66302996/
我已经写了并且 npm 发布了这个:https://github.com/justin-calleja/pkg-dependents 现在我正在用 Typescript 编写这个包:https://g
我有一个函数,我想在 TypeScript 中模拟它以进行测试。在我的测试中,我只关心 json和 status .但是,当使用 Jest 的 jest.spyOn 时我的模拟函数的类型设置为返回 h
我正在使用一个库 (Axios),它的包中包含 Typescript 声明。 我想声明一个将 AxiosResponse(在库的 .d.ts 文件中声明)作为参数的函数。我有以下内容: functio
我是 Typescript 的新手。我想使用 将一个 Typescript 文件加载到另一个 Typescript 文件中标签。 我做了一些事情,但它不起作用!请帮助我。 first.ts: imp
为什么我会收到下面屏幕截图中显示的错误? Atom 说我的 tsconfig.json“项目文件包含无效选项”用于 allowJs、buildOnSave 和 compileOnSave。 但是应该允
所以我正在创建一个 TypeScript 库,我可以轻松地将所有生成的 JS 文件编译成一个文件。有没有办法将所有 .ts 和 .d.ts 编译成一个 .ts 文件? 除了支持 JS 的版本(较少的智
Microsoft Research 提供了一种名为Safer TypeScript 的新 TypeScript 编译器变体: http://research.microsoft.com/en-us/
我需要这个来在单个文件中分发 TypeScript 中的库。有没有办法将多个 typescript 文件合并到(一个js文件+一个 typescript 定义)文件中? 最佳答案 要创建一个库,您可以
用例:我想知道一个函数在 typescript 中执行需要多少时间。我想为此目的使用装饰器。我希望装饰器应该返回时间以便(我可以进一步使用它),而不仅仅是打印它。 例如: export functio
我想检查一个类型是否可以为 null,以及它是否具有值的条件类型。 我尝试实现 type IsNullable = T extends null ? true : false; 但是好像不行 type
我的问题是基于这个 question and answer 假设我们有下一个代码: const myFn = (p: { a: (n: number) => T, b: (o: T) => v
我知道双重否定前缀,我知道 TypeScript 的单后缀(非空断言)。 但是这个双后缀感叹号是什么? /.*验证码为(\d{6}).*/.exec(email.body!!)!![1] 取自here
我正在使用以下文件结构在 Webstorm 中开发一个项目 | src | ... | many files | types | SomeInterface |
在 TypeScript 类中,可以为属性声明类型,例如: class className { property: string; }; 如何在对象字面量中声明属性的类型? 我试过下面的代码,但它
我正在寻找一种在不丢失推断类型信息的情况下将 TypeScript 中的文字值限制为特定类型的好方法。 让我们考虑一个类型Named,它保证有一个名字。 type Named = { name:
在 TypeScript 中,我想创建一个联合类型来表示属于一个或多个不同类型的值,类似于 oneOf在 OpenAPI或 JSON Schema .根据a previous answer on a
type Func = (foo:string) => void // function expression const myFunctionExpression:Func = function(f
假设我有一个联合类型,我正在使用类似 reducer 的 API 调用模式,看起来像这样: type Action = { request: { action: "create
我在 typescript 中有以下去抖功能: export function debounce( callback: (...args: any[]) => void, wait: numb
在 Vue3 的 defineComponent 函数中,第一个泛型参数是 Props,所以我在这里使用 Typescript 接口(interface)提供我的 props 类型。喜欢: expor
我是一名优秀的程序员,十分优秀!