程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了定义 1...n 个字符串模板类型的通用交集类型大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决定义 1...n 个字符串模板类型的通用交集类型?

开发过程中遇到定义 1...n 个字符串模板类型的通用交集类型的问题如何解决?下面主要结合日常开发的经验,给出你关于定义 1...n 个字符串模板类型的通用交集类型的解决方法建议,希望对你解决定义 1...n 个字符串模板类型的通用交集类型有所启发或帮助;

我正在尝试利用字符串模板文字类型的强大功能为用于定义路由的字符串添加类型安全性。

  • 例如,没有参数的路由可以是任何 String
  • 具有单个参数的路由必须在路径字符串中包含 :parametername 并且在 parametername 对象中包含 params 作为键/值。

我可以手动设置这些类型,而且效果很好。但是我想做的是找到一种方法来消除开发人员手动链接交叉点的需要。我想在我的图书馆里处理。

type DynamicParam<S extends String> = `:${S}`
type DynamicParamRoute<T extends String> = `${String}/${DynamicParam<T>}/${String}` | `${DynamicParam<T>}/${String}` | `${String}/${DynamicParam<T>}` | `${DynamicParam<T>}`

type UserParamRoute = DynamicParamRoute<'user'>

// const bad1: UserParamRoute = 'user' // error as doesn't match ":user"
const u1: UserParamRoute = ':user'
const u2: UserParamRoute = 'prefix/:user'
const u3: UserParamRoute = ':user/suffix'
const u4: UserParamRoute = 'prefix/:user/suffix'

type TeamParamRoute = DynamicParamRoute<'team'>

const t1: TeamParamRoute = ':team'
const t2: TeamParamRoute = 'prefix/:team'
const t3: TeamParamRoute = ':team/suffix'
const t4: TeamParamRoute = 'prefix/:team/suffix'


// Combining them to get safety on a multi-param route String

type UserTeamParamRoute = UserParamRoute & TeamParamRoute // ***** I don't want my library consumer to be responsible for this. ******

// const ut1: UserTeamParamRoute = 'user/team'  // Type '"user/team"' is not assignable to type 'UserTeamParamRoute'.ts(2322)
// const ut1: UserTeamParamRoute = ':user'      // Type '":user"' is not assignable to type 'UserTeamParamRoute'.ts(2322)
// const ut1: UserTeamParamRoute = ':team'      // Type '":team"' is not assignable to type 'UserTeamParamRoute'.ts(2322)

const ut1: UserTeamParamRoute = ':user/:team'
const ut2: UserTeamParamRoute = 'prefix/:user/:team'
const ut3: UserTeamParamRoute = ':user/:team/suffix'
const ut4: UserTeamParamRoute = ':user/mIDdle/params/:team'
const tu1: UserTeamParamRoute = ':team/:user'
const tu2: UserTeamParamRoute = 'prefix/:team/:user'
const tu3: UserTeamParamRoute = ':team/:user/suffix'
const tu4: UserTeamParamRoute = ':team/mIDdle/params/:user'

我尝试了一种对 params 对象使用 keyof 的方法,但它创建了键的联合。路由定义需要 params 对象,特别是如果有动态参数。因此,使用它的键来生成路由的 path 所需的类型似乎太完美了。

const params = {
  user: 'someTing',team: 'someotherthing'
} as const

const ps = ['user','team'] as const

type Params = keyof typeof params


// Doesn't work,no intersection to force requiring all the keys. Just union of everything
type RouteParams = DynamicParamRoute<Params> // type RouteParams = ":user" | `${String}/:user/${String}` | `:user/${String}` | `${String}/:user` | ":team" | `${String}/:team/${String}` | `:team/${String}` | `${String}/:team`

const r1: RouteParams = ':user' // means this is valID
const p1: RouteParams = ':team' // so is this
// const rp: RouteParams = 'userteam'
// const rp0: RouteParams = ''
// const rp01: RouteParams = 'missingall'
const rp1: RouteParams = ':user/:team'
const rp2: RouteParams = 'prefix/:user/:team'
const rp3: RouteParams = ':user/:team/suffix'
const rp4: RouteParams = ':user/mIDdle/params/:team'
const pr1: RouteParams = ':team/:user'
const pr2: RouteParams = 'prefix/:team/:user'
const pr3: RouteParams = ':team/:user/suffix'
const pr4: RouteParams = ':team/mIDdle/params/:user'

提前感谢您提供的任何见解!

更新:jcalz 解决方案以 GIF 格式演示(我希望它不会太压缩)

[

定义 1...n 个字符串模板类型的通用交集类型

解决方法

在 TypeScript 中可以通过某种类型的杂耍将有问题的联合置于 transform unions to intersections 位置来 contravariant。下面是我如何重新定义 DynamicParamRoute<T>,以便 T 中的联合在输出中变成交集:

type DynamicParamRoute<T extends String> = (T extends any ? (x:
    `${String}/${DynamicParam<T>}/${String}` | 
    `${DynamicParam<T>}/${String}` | 
    `${String}/${DynamicParam<T>}` | 
    `${DynamicParam<T>}`
) => void : never) extends ((x: infer I) => void) ? I : never;

我已经用 (T extends any ? (x: OrigDefinition<T>) => void : never) extends ((x: infer I) => void) ? I : never; 封装了您的原始定义。这需要 T 和 diStributes 中的联合,以便 OrigDefinition<T> 分别应用于每个部分,并将它们作为函数参数(逆变)放在 inferring 与它们的交集之前.它有点毛茸茸,但最终它会产生你想要的类型:

type RouteParams = DynamicParamRoute<Params>
/* (":user" | `${String}/:user/${String}` | `:user/${String}` | `${String}/:user`) & 
(":team" | `${String}/:team/${String}` | `:team/${String}` | `${String}/:team`) */

导致您想要的错误:

const r1: RouteParams = ':user' // error!
const p1: RouteParams = ':team' // error!

我不确定模式模板文字类型的联合交集在实践中的规模如何,但这无论如何都超出了问题的范围。

Playground link to code

大佬总结

以上是大佬教程为你收集整理的定义 1...n 个字符串模板类型的通用交集类型全部内容,希望文章能够帮你解决定义 1...n 个字符串模板类型的通用交集类型所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。