gpt4 book ai didi

javascript - 使用 Typescript 声明字符串结构的最佳方法?

转载 作者:行者123 更新时间:2023-12-05 03:16:55 26 4
gpt4 key购买 nike

假设我有这个 JavaScript 对象:

const myObject = {
id: 'my_id', // Base value that following value's structures will be depended on (always pascal case).
upperID: 'MY_ID', // Uppercase of `id`.
camelID: 'myId', // Camel case of `id`.
}

我想使用 TypeScript 来确保 id 始终是 pascal 小写。 upperIDcamelID 具有与上述不同的字符串结构的相同“值”。在 TypeScript 中声明此 myObject 类型的最佳方式是什么?

最佳答案

使用提供的 Uppercase<T> 大写字母非常容易实用程序类型。

type CasedIds<ID extends string> = {
id: ID,
upperID: Uppercase<ID>
}


const myObject: CasedIds<'my_id'> = {
id: 'my_id',
upperID: 'MY_ID',
} as const

See playground


Camel 案例变得棘手。因此,首先您需要一个可以对字符串执行此操作的类型。

可能有几种方法可以做到这一点。这是一个。

type CamelCase<T extends string> =
T extends `${infer Pre}_${infer Letter}${infer Post}`
? `${Pre}${Capitalize<Letter>}${CamelCase<Post>}`
: T

type TestCamel = CamelCase<'abc_def_ghi'> // 'abcDefGhi'

See playground

让我们来看看这个。

这个泛型以字符串类型作为泛型参数T .然后检查是否 T扩展包含下划线后跟一些字符的特定模式的字符串。

如果是,则从该模式中推断出一些子字符串。推断下划线前的部分为Pre , 下划线后的字符为 Letter字符串的其余部分为 Post .否则,只需按原样使用字符串类型即可。

然后我们可以从 Pre 中创建一个新字符串Letter大写,Post .但可能还有更多下划线,所以我们在 Post 上再次执行整个操作.这是一种递归类型,当没有下划线时停止递归。


剩下的就很简单了:

type CamelCase<T extends string> =
T extends `${infer Pre}_${infer Letter}${infer Post}`
? `${Pre}${Capitalize<Letter>}${CamelCase<Post>}`
: T

type CasedIds<ID extends string> = {
id: ID,
upperID: Uppercase<ID>
camelID: CamelCase<ID>
}


const myObject: CasedIds<'my_id'> = {
id: 'my_id',
upperID: 'MY_ID',
camelID: 'myId',
} as const

See playground


尽管您可能需要一个函数为您构建这些:

function makeId<T extends string>(id: T): CasedIds<T> {
return {} as unknown as CasedIds<T> // mock a real implementation
}

const myId = makeId('my_id')
myId.id // type: 'my_id'
myId.upperID // type: 'MY_ID'
myId.camelID // type: 'myId'

See playground

关于javascript - 使用 Typescript 声明字符串结构的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74382893/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com