简体   繁体   English

Typescript 编译器不执行相关 generics

[英]Typescript compiler not enforcing related generics

Consider the below example:考虑以下示例:

interface Type<T>{
    new (...args:any):T;
}

interface Holder<T>{
    data:T
}

class StringHolder implements Holder<string>{
    constructor(public data:string){};
}

class BooleanHolder implements Holder<boolean>{
    constructor(public data:boolean){};
}

class FakeBooleanHolder {
    data = true;
}

function accept<E extends Holder<T>,T>(clazz:Type<E>, data:T){
    console.log(clazz,data);
}

// expected: OK
accept(StringHolder,'text');
accept(BooleanHolder, false);

// expected: Compile Error
accept(StringHolder,true);
accept(BooleanHolder,'text')

// expected: Compile Error
// actual: OK 
// Why "E extends Holder<T>"  is not enforced by compiler ? 
// Here T is boolean, Hence, E should be Type<? extend Holder<boolean>>, why its not ?
accept(FakeBooleanHolder,true);

TS Playground Link TS 游乐场链接

Question is same as commented in above code:问题与上面代码中的评论相同:

  1. Why E extends Holder<T> is not enforced by compiler?为什么E extends Holder<T>不是由编译器强制执行的?
  2. Is compiler unable to relate E with T ?编译器是否无法将ET关联起来?
  3. Does the structural similarity of FakeBooleanHolder overrides explicit type declaration E extends Holder<T> ? FakeBooleanHolder的结构相似性是否会覆盖显式类型声明E extends Holder<T>
  4. Is there an issue with signature of accept() function? accept() function 的签名有问题吗? (@Aleksey 's answer has a different variant of Type ) (@Aleksey 的回答有不同的Type变体)

Putting structural types concern aside, to restrict the data param to be of the same type as data in passed Holder<T> constructor:抛开结构类型问题,将data参数限制为与传递的Holder<T>构造函数中的data类型相同:

function acceptHolderClassAndData<T, H extends new (...args: any[]) => Holder<T>>(clazz: H, data: T): void {
    console.log(clazz, data);
}

acceptHolderClassAndData(StringHolder, 'str') // OK
acceptHolderClassAndData(BooleanHolder, true) // OK

acceptHolderClassAndData(StringHolder, true) // Error
acceptHolderClassAndData(BooleanHolder, 123) // Error

Playground 操场

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

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