Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 如何编写抽象类型脚本泛型类型?_Typescript_Generics_Typescript Generics - Fatal编程技术网

Typescript 如何编写抽象类型脚本泛型类型?

Typescript 如何编写抽象类型脚本泛型类型?,typescript,generics,typescript-generics,Typescript,Generics,Typescript Generics,鉴于以下类型 接口基础{ id:字符串; } 接口A扩展了基础{ 普罗帕:弦; } 接口B扩展了基础{ propB:字符串; } 我想用以下约束条件表达一个通用的MyGeneric: T必须是对象 T键必须是string T值必须是基实例(要么是基类型,要么是扩展基类型) (3.wasT值必须与Base接口兼容,但已重新编写,以避免不理解) 我试过了 接口MyConstraint{ [键:字符串]:基 } 接口MyGeneric{ 数据:T } 但在这种情况下,当用户想要使用它时,它有两个缺

鉴于以下类型

接口基础{
id:字符串;
}
接口A扩展了基础{
普罗帕:弦;
}
接口B扩展了基础{
propB:字符串;
}
我想用以下约束条件表达一个通用的
MyGeneric

  • T
    必须是对象
  • T
    键必须是
    string
  • T
    值必须是
    基实例
    (要么是
    基类型
    ,要么是扩展基类型)

    (3.was
    T
    值必须与
    Base
    接口兼容,但已重新编写,以避免不理解)

  • 我试过了

    接口MyConstraint{
    [键:字符串]:基
    }
    接口MyGeneric{
    数据:T
    }
    
    但在这种情况下,当用户想要使用它时,它有两个缺点:

    type MyConstraint<T> = {
      [K in keyof T]: T[K] extends Base ? T[K] : never;
    };
    
    interface MyGeneric<T extends MyConstraint<T>> {
      data: T;
    }
    
    接口用户定义接口1{
    a:a;
    b:b;
    }
    函数foo1(p:MyGeneric):void{
    //缺点1:这会引发TS2344:
    //类型“userDefinedInterface1”不满足约束“userDefinedInterface1”。//类型“userDefinedInterface1”中缺少索引签名。
    }
    //要解决缺点1,用户必须扩展MyConstraint
    接口userDefinedInterface2扩展了MyConstraint{
    a:a;
    b:b;
    }
    函数foo2(p:MyGeneric):void{
    //缺点2:在这里,ts认为每个字符串属性都是有效的,因为[key:string]
    console.log(p.data.arbirykey);//这是有效的
    }
    

    有没有办法定义
    接口MyGeneric
    以遵守上述3个约束条件而不存在这2个缺点?

    只有一个限制-如果要添加额外的键,必须指定它们

    接口基础{
    id:字符串;
    num:数字;
    }
    接口A扩展了基础{
    普罗帕:弦;
    }
    接口B扩展了基础{
    propB:字符串;
    }
    类型MyGeneric={
    数据:T&{
    [key in K | keyof T]:key扩展了keyof T?T[key]:字符串;
    }
    }
    常量test1:MyGeneric={
    数据:{
    id:'123',
    总数:123,
    建议B:‘123’,
    测试:'123',
    },
    };
    常量test2:MyGeneric={
    数据:{
    id:'123',
    总数:123,
    建议B:‘123’,
    测试:“123”,//失败,必须在当前TS中提供。
    },
    };
    

    如果您只想依靠
    T
    的键

    然后只需使用此版本:

    类型MyGeneric={
    数据:T&{
    [key in keyof T]:key扩展keyof Base?Base[key]:字符串;
    }
    }
    
    只有一个限制-如果要添加额外的密钥,必须指定它们

    接口基础{
    id:字符串;
    num:数字;
    }
    接口A扩展了基础{
    普罗帕:弦;
    }
    接口B扩展了基础{
    propB:字符串;
    }
    类型MyGeneric={
    数据:T&{
    [key in K | keyof T]:key扩展了keyof T?T[key]:字符串;
    }
    }
    常量test1:MyGeneric={
    数据:{
    id:'123',
    总数:123,
    建议B:‘123’,
    测试:'123',
    },
    };
    常量test2:MyGeneric={
    数据:{
    id:'123',
    总数:123,
    建议B:‘123’,
    测试:“123”,//失败,必须在当前TS中提供。
    },
    };
    

    如果您只想依靠
    T
    的键

    然后只需使用此版本:

    类型MyGeneric={
    数据:T&{
    [key in keyof T]:key扩展keyof Base?Base[key]:字符串;
    }
    }
    
    我认为这应该解决您的两个缺点:

    type MyConstraint<T> = {
      [K in keyof T]: T[K] extends Base ? T[K] : never;
    };
    
    interface MyGeneric<T extends MyConstraint<T>> {
      data: T;
    }
    

    您会得到一个错误,指出属性类型
    c
    不兼容。

    我认为这应该解决您的两个缺点:

    type MyConstraint<T> = {
      [K in keyof T]: T[K] extends Base ? T[K] : never;
    };
    
    interface MyGeneric<T extends MyConstraint<T>> {
      data: T;
    }
    

    如果使用
    MyGeneric
    ,您会得到一个错误,说属性类型
    c
    不兼容。

    它说如果使用
    MyGeneric
    ,则
    propB
    永远不应该兼容:也许我当时误解了这个问题-我认为您的约束应该是一个对象,对象的值为
    Base
    B
    扩展了
    Base
    ,但它与您描述的
    T
    类型(第3点)不匹配。他问:T必须是一个对象,T键必须是字符串,T值必须与基本接口兼容
    B
    是一个对象,
    B
    键是字符串,
    B
    Base
    兼容,但是
    MyGeneric
    不允许说
    string
    应该是
    never
    ,这违反了第二个要求。似乎我使用了一个糟糕的措辞,导致了不理解。我认为@JánJakubNaništa做对了:我应该为第二个要求编写:
    T
    值必须是
    instanceOf Base
    (要么是类型基,要么是类型扩展基。我将用此更正编辑我的帖子。在这种情况下,如果我理解正确,
    B
    不应该是
    MyGeneric
    的有效类型参数,因为它的值没有扩展
    Base
    正确吗?因此
    MyGeneric
    确实应该给您一个错误。但是,例如
    MyGeneric
    应该可以。那么我的答案正确吗?它说如果使用
    MyGeneric
    就永远不应该使用
    propB
    :也许我当时误解了这个问题-我认为你的约束应该是一个对象,对象的值应该是
    Base
    B
    扩展
    Base
    ,但它与不匹配de>T您描述的类型(第3点)你能澄清一下吗?他问:T必须是一个对象,T键必须是字符串,T值必须与基本接口兼容。
    B
    是一个对象,
    B
    键是字符串,
    B
    Base
    兼容,但是
    MyGeneric
    不允许它说
    string
    应该是
    永远不
    ,这是错误的ks第二个要求。我似乎使用了一个糟糕的措辞,导致了不理解。我认为@JánJakubNaništa说得对:我应该为第二个要求编写:
    T
    值必须是
    instanceOf Base
    (要么是类型基,要么是类型扩展基。我将用此更正编辑我的帖子。在这种情况下,如果我理解正确,
    B
    不应该是有效的类型argum