【发布时间】:2021-04-25 15:27:24
【问题描述】:
假设您有多个模块,并且您希望每个模块都导出某种特定形状的对象。同时,对象的属性可能具有您想要在导入模块时推断的变量类型。有没有办法声明对象的类型(这样你在编写对象时可以自动完成),而且还能够推断出特定对象的属性类型?
这是一个显然不起作用的示例,因为我们明确设置要推断的类型:
type MyObject<T> = { myProp: T }
// moduleA.ts
export const a: MyObject<any> = ({ myProp: 42 });
// moduleB.ts
export const b: MyObject<any> = ({ myProp: "A string" });
// index.ts
import { a } from "./moduleA";
import { b } from "./moduleB";
const objectMap = { a, b };
type ObjectMap = typeof objectMap
type InferredMap = {
[P in keyof ObjectMap]: ObjectMap[P] extends { myProp: infer R } ? R : unknown
}
不出所料,结果类型是{ a: any, b: any }。
我们如何在编写模块时保持自动完成的同时保持{ a: number, b: string }?
我了解,如果我避免明确提供 a 和 b 的类型,则会推断出这些类型。但是在编写模块时我失去了自动完成功能(即我无法开始输入 m 并看到 myProp 是一个有效的属性)。
同样,我不想要求用户明确地向MyObject 提供类型。在这个例子中,它只是一个number 或string,但实际上这种类型可能非常复杂,我不希望用户在他们已经写出确定输入。
此外,我知道我可以使用单个模块和一个函数来做到这一点,例如:
type MappedType<
T extends { [key: string]: { myProp: any } }
> = {
[P in keyof T]: T[P] extends { myProp: infer R } ? R : unknown
}
function getResult<T extends { [key: string]: { myProp: any } }> (map: T): MappedType<T> {
//
}
但问题是如何跨模块边界实现相同的结果?
【问题讨论】:
-
诀窍是你需要通过一个函数来创建你的对象。和我前几天写的这个答案基本一致:stackoverflow.com/a/67221364/10431574
标签: typescript