首页 > 解决方案 > 通过一个属性更改将现有类型转换为新类型

问题描述

如何通过一个属性更改将现有类型转换为新类型?

Typesctipt 沙箱

例子:

type SomeComplexType = string // just for example

// cannot be changed
type Options<T> = {
    opt1: boolean | undefined;
    opt2: number;
    opt3?: SomeComplexType;
    opt4: T
}

// Can be changed

// How to change opt1 to accept only true and infer other option types?
type Keys = keyof Options<any>

let r: { [K in Keys]: K extends 'opt1' ? true : any }

// Good (should work)
r = { opt1: true, opt2: 2, opt3: '1', opt4: 1 }
r = { opt1: true, opt2: 2, opt3: '1', opt4: 'str' }

// Bad (should be error)
r = { opt1: false, opt2: 1, opt3: 'str', opt4: 1 } // opt1 should be true
r = { opt1: true, opt2: 'str', opt3: 'str', opt4: 1 } // opt2 should be number
r = { opt1: true, opt2: 'str', opt3: 1, opt4: 1 } // opt3 should be 

标签: typescript

解决方案


如果你有一个对象类型O并且想要创建一个新类型,其中所有的属性键和值都是相同的,除了 key 的属性opt1应该是true,你可以这样写:

{ [K in keyof O]: K extends 'opt1' ? true : O[K] }

语法O[K]索引访问,意思是“具有类型键的属性的O类型K”。

然后您的示例应该按需要工作,(假设OOptions<any>):

// Good 
r = { opt1: true, opt2: 2, opt3: '1', opt4: 1 } // okay
r = { opt1: true, opt2: 2, opt3: '1', opt4: 'str' } // okay

// Bad 
r = { opt1: false, opt2: 1, opt3: 'str', opt4: 1 } // error!
r = { opt1: true, opt2: 'str', opt3: 'str', opt4: 1 } // error!
r = { opt1: true, opt2: 'str', opt3: 1, opt4: 1 } // error!

Playground 代码链接


推荐阅读