程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何在 Typescript 中输入匹配/折叠功能大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决如何在 Typescript 中输入匹配/折叠功能?

开发过程中遇到如何在 Typescript 中输入匹配/折叠功能的问题如何解决?下面主要结合日常开发的经验,给出你关于如何在 Typescript 中输入匹配/折叠功能的解决方法建议,希望对你解决如何在 Typescript 中输入匹配/折叠功能有所启发或帮助;

我尝试了一段时间来为匹配/折叠函数编写正确的类型。希望有人能帮助我了解我做错了什么。

该函数应该是通用的,但请虑以下联合类型作为示例。

class Square {
  type = "Square" as const
  constructor(public sIDe: number) {}
}
class Circle {
  type = "Circle" as const
  constructor(public radius: number) {}
}
class Rectangle {
  type = "Rectangle" as const
  constructor(public wIDth: number,public height: number) {}
}

type Shape = Square | Circle | Rectangle

我希望有一个匹配函数,这样我就可以处理所有选项并为此具有类型安全性。它有点适用于这个解决方案。

type XMap<T,Key extends keyof T> = { [K in T[Key]]: T extends { type: K } ? T : never }

type XPattern<T,Key extends keyof T,R> = { [K in keyof XMap<T,Key>]: (shape: XMap<T,Key>[K]) => R }

function matcher<T,R>(key: Key,pattern: XPattern<T,Key,R>): (shape: T) => R {
  return shape => pattern[shape[key]](shape as any)
}

const area = matcher<Shape,'type',number>('type',{
  Square: square => square.sIDe * square.sIDe,Circle: circle => circle.radius * circle.radius * Math.PI,Rectangle: rect => rect.height * rect.wIDth
})

const shapes = [new Circle(4.0),new Square(5.0),new Rectangle(6.0,7.0)]

console.log(`Areas: ${shapes.map(area)}`)

Playground Link

正如你在这个 Playground 中看到的,它仍然会给出错误,但不知何故向我展示了匹配器中的正确类型。不知道如何解决这个问题。

感谢您的时间和帮助。

解决方法

这是让它工作的一种方法。请注意,为了匹配目的,我必须使用不同的类型:

type Shape = Square | Circle | Rectangle

/**
 * Given a type,a key on that type,and a potential value,* return if type is an object that extends { [key]: value }
 * 
 * Since union types diStribute over conditionals (it tries one at a timE),* this lets us start out with Shape and end up with a single of the three
 */
type XMatching<T,TKey extends keyof T,TValue> = T extends { [P in TKey]: TValue } 
  ? T 
  : never

type Test01 = XMatching<Shape,'type','Circle'> // Circle
type Test02 = XMatching<Shape,'Square' | 'Circle'> // Square | Circle
type Test03 = XMatching<Shape,'type2','Square'> // ERR since `type2` is not a shared field
type Test04 = XMatching<Shape,'Ellipse'> // never

/**
 * Given a type T,a key on that type TK,and another arbitrary type TR,* if type.key extends String (and therefore can be used as a key itself)
 * generate a map from all possible values of type.key to 
 * functions that take in the particular object with that particular value of type.key,e.g.
 * 
 * 'Circle' -> Circle
 * 'Square' -> Square
 * 
 * and returns the arbitrary type TR.
 * 
 * Otherwise,return never.
 * 
 * (there are certainly ways to write this without the conditional)
 */
type XPattern<T,TR> = T[TKey] extends String
  ? { [P in T[TKey]]: (matched: XMatching<T,TKey,P>) => TR }
  : never

function matcher<T,TR>(key: TKey,pattern: XPattern<T,TR>): (matched: T) => TR {
  return shape => pattern[shape[key]](shapE)
}

const shapes = [new Circle(4.0),new Square(5.0),new Rectangle(6.0,7.0)]

const area = matcher<Shape,number>('type',{
  Square: square => square.side * square.side,Circle: circle => circle.radius * circle.radius * Math.PI,Rectangle: rect => rect.height * rect.width
}) // OK!

const badArea01 = matcher<Shape,Rectangle: rect => rect.height * rect.width,Ellipse: ellipse => ellipse.radiusA * ellipse.radiusB * Math.PI 
}) // ERR since Ellipse has no match

const badArea02 = matcher<Shape,Rectangle: rect => "real big!" 
}) // ERR since returns a String,not a number

大佬总结

以上是大佬教程为你收集整理的如何在 Typescript 中输入匹配/折叠功能全部内容,希望文章能够帮你解决如何在 Typescript 中输入匹配/折叠功能所遇到的程序开发问题。

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

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