typescript - 在 typescript 中我可以映射一个类型来拥有吗?当属性的相应值满足某个条件时?

标签 typescript

例如,给定一个对象:

const TypeDef1 = {
    foo: {optional: true, type: 'string'},
    bar: {type: 'number'}
}

符合类型,比如说

type TypeDef = {
    [key: string]: {
        optional?: boolean,
        type: 'number' | 'string' | 'boolean'
    }
}

我想要一些可重复使用的打字 Transform<T extends TypeDef>这样

Transform<typeof TypeDef1>

给出:

{
    foo?: string
    bar: number
}

这在 Typescript 中可能吗?

最佳答案

您可以使用映射类型和条件类型的组合将类型定义转换为实际类型(前提是我们还在定义上使用 as const 断言以确保保留所有类型信息。


type TypeDef =  { [key: string]: { optional?: boolean, type: 'number' | 'string' | 'boolean' } };
type TypeNameToType = {
    number: number,
    string: string,
    boolean: boolean
}
type TypeDefToType<T extends TypeDef> = {
    // The optional properties
    -readonly [P in keyof T as T[P]['optional'] extends true ? P: never]?: TypeNameToType[T[P]['type']]
} & {
    // The mandatory properties
    -readonly [P in keyof T as T[P]['optional'] extends true ? never: P]: TypeNameToType[T[P]['type']]
}

const TypeDef1 = {
    foo: {optional: true, type: 'string'},
    bar: {type: 'number'}
} as const


type X = TypeDefToType<typeof TypeDef1>
//   ^?
// type X = {
//     foo?: string | undefined;
// } & {
//     bar: number;
// }

Playground Link

关于typescript - 在 typescript 中我可以映射一个类型来拥有吗?当属性的相应值满足某个条件时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71291628/

相关文章:

typescript - 如何将 date-fns 与 TypeScript 一起使用?

node.js - 如何对 NestJS 中的 Controller 应用防护进行单元测试?

angular - indexof 不是 typescript 中的函数,而基于数字进行过滤

javascript - 当没有公开 viewController 时,如何将 cocoapod 转换为 typescript ?

typescript - 在 TypeScript 参数签名中处理潜在的空参数

javascript - 如何从 typescript 上的txt文件获取数据?

javascript - GetElementById 与 Dom 迭代

node.js - 为什么在 typescript 中声明了一个全局 `name` 变量,我可以避免使用它吗?

javascript - 在 TypeScript 中将任意函数参数推断为对象或元组类型

javascript - 将 Angular 1.x Controller 转换为 TypeScript 时出现问题