简体   繁体   English

如何强制执行泛型类型 typescript function

[英]How to enforce generic types typescript function

I have the following function signature:我有以下 function 签名:

const renderMessage = <T extends A | B > 
(
  a: T,
  b: Map<T, Array<string>>, 
  c: T,
) => {

My problem is that I can call this function as follows:我的问题是我可以这样称呼这个 function :

type A = "A" | "B"
type B = "Z" | "Y"
let myA: A = "A"
let myB: B = "Z"
let myAMap: Map<A,Array<string>> = new Map(...)
let myBMap: Map<B,Array<string>> = new Map(...)
renderMessage(myA, myBMap, myA) // I want error here
renderMessage(myB, myAMap, my B) // I want error here

The reason for being able to do this is explained here . 这里解释了能够做到这一点的原因。 If I understood correctly, the structure of my Map object does not change based on T being A or B, so typescript won't complain.如果我理解正确,我的Map object 的结构不会因为 T 是 A 或 B 而改变,所以 typescript 不会抱怨。 However, I am struggling to figure out how to enforce this.但是,我正在努力弄清楚如何执行此操作。

EDIT编辑

They are types and not classes.它们是类型而不是类。 See Playground Link游乐场链接

The T type is too ambiguous for the TypeScript inference. T型对于 TypeScript 推断来说太模糊了。 It resolves to the most narrow type that makes the whole signature work: A | B它解析为使整个签名工作的最窄类型: A | B A | B . A | B

I guess you just have to provide it yourself between angle brackets:我想你只需要在尖括号之间自己提供它:

TypeScript playground TypeScript操场

The reason to have different classes - A and B - should be if one type of instance should hold differently structured data from the other, or if one type of instance should have different methods.具有不同类(A 和 B)的原因应该是一种类型的实例应该保存与另一种不同的结构化数据,或者一种类型的实例应该具有不同的方法。 If the data is structured the same way, and the methods are all the same as well, then there shouldn't be separate classes.如果数据的结构相同,方法也都相同,那么就不应该有单独的类。

If you distinguish A and B in any way, the error will arise as desired:如果您以任何方式区分 A 和 B,则会根据需要出现错误:

class A{
  x = 'x'
}
class B{
  y = 'g'
}
const renderMessage = <T extends A | B > 
(
  a: T,
  b: Map<T, Array<string>>, 
  c: T,
) => {
}

let myA: A = new A()
let myB: B = new B()
let myAMap: Map<A,Array<string>> = new Map(...)
let myBMap: Map<B,Array<string>> = new Map(...)
renderMessage(myA, myBMap, myA) // I want error here
renderMessage(myB, myAMap, myB) // I want error here

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM