Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.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 - Fatal编程技术网

Typescript-实现泛型类型的类实例

Typescript-实现泛型类型的类实例,typescript,generics,Typescript,Generics,我有一个使用泛型接口创建类的函数。实例的属性由该泛型的参数设置,如下所示: const ClassFactory=()=>{ 类MyClass{ 建造商(数据:T){ for(常量输入数据){ 如果(!data.hasOwnProperty(key)){continue;} (此为任意)[key]=数据[key]; } } //其他方法也可以在这里使用 } 返回MyClass; } const GeneratedClass=ClassFactory(); const myInstance=新生

我有一个使用泛型接口创建类的函数。实例的属性由该泛型的参数设置,如下所示:

const ClassFactory=()=>{
类MyClass{
建造商(数据:T){
for(常量输入数据){
如果(!data.hasOwnProperty(key)){continue;}
(此为任意)[key]=数据[key];
}
}
//其他方法也可以在这里使用
}
返回MyClass;
}
const GeneratedClass=ClassFactory();
const myInstance=新生成的类({id:1});
console.log((myInstance as any).id);//日志1
这按预期运行,但存在两个问题

  • myInstance
    typings没有t键-我希望
    myInstance.id
    是一个数字
  • 我必须将
    转换为构造函数中的任何
    ,以通过给定数据分配值
  • 为了解决第一个问题,我尝试了从其他帖子中看到的各种方法,包括
    类MyClass实现T
    ,但它们都会导致相同的错误:
    类只能实现对象类型或对象类型与静态已知成员的交集。ts(2422)
    。 我理解为什么会发生这种情况,但是,既然定义类时知道
    T
    ,那么有没有办法做到这一点

    如果我在
    公共数据:T
    属性中有数据,那么
    myInstance.data.id
    是正确键入的。所以我的问题是,可以跳过
    .data
    部分吗


    提前感谢

    受Jonas Wilms评论的启发,我让它工作了,即使类返回了方法/静态

    但是,如果在类方法中使用了
    new MyClass()
    ,则这种方法无法正常工作

    它工作的一个变通方法是创建一个返回具有正确类型的实例的静态文件

    完整的工作示例

    const ClassFactory=()=>{
    类MyClass{
    建造商(数据:T){
    for(常量输入数据){
    如果(!data.hasOwnProperty(key)){continue;}
    (此为任意)[key]=数据[key];
    }
    }
    公共静态生成(数据:T):T&实例类型{
    将新的MyClass(数据)返回为T&InstanceType;
    }
    公共静态someStatic(){
    返回2;
    }
    公共方法(){
    返回3;
    }
    }
    将MyClass返回为(新的(数据:T)=>T&InstanceType)和MyClass的类型;
    }
    const GeneratedClass=ClassFactory();
    const myInstance=新生成的类({id:1});
    log(myInstance.id,GeneratedClass.someStatic(),myInstance.someMethod());
    const myBuiltInstance=GeneratedClass.build({id:1});
    log(MyBuilInstance.id,GeneratedClass.someStatic(),MyBuilInstance.someMethod());
    
    我刚刚遇到了这个问题,通过简单地抛弃
    new
    并创建一个通用的静态方法
    Class.create()
    ,在这里我实例化并强制转换为正确的类型,就可以非常优雅地解决这个问题

    接口MyGenericInterface{
    getTheThing():T
    }
    类MyClass实现MyGenericInterface{
    //使构造函数私有以执行合同
    私有构造函数(私有对象:any){}
    public getTheThing():任何{
    归还这个东西
    }
    静态创建(thing:typeof thing){
    将新的MyClass(thing)作为MyGenericInterface返回
    }
    }
    const stringyinstanceError=new MyClass('thing')//错误
    const stringyInstance=MyClass.create('thing')
    const stringThing:string=stringyInstance.getTheThing()
    constnumberinstance=MyClass.create(123)
    常量numberythingError:string=numberInstance.getTheThing()//错误
    常量numberyThing:number=numberinstance.getTheThing()//有效!
    
    为什么使用
    javascript
    标记?请尝试
    将MyClass返回为{new():T}
    @jonaswillms谢谢您的评论。通过使用
    将MyClass返回为{new(数据:T):T}对于上面的示例,它工作正常,但是如果类中有任何方法,它就会失败。理想情况下,它会覆盖新的
    ,而不是整个类。我认为如果你回答自己的问题,你应该将其作为答案而不是问题的编辑发布。@jcalz是的,刚刚做了,谢谢大家的时间和提示
    const ClassFactory = <T>() => {
    
        class MyClass {
            constructor(data: T) {
                for (const key in data) {
                    if (!data.hasOwnProperty(key)) { continue; }
                    (this as any)[key] = data[key];
                }
            }
    
            // other methods can be here
        }
    
        return MyClass;
    }
    
    const GeneratedClass = ClassFactory<{ id: number }>();
    
    const myInstance = new GeneratedClass({ id: 1 });
    
    console.log((myInstance as any).id); // logs 1
    
    
    return MyClass as (new (data: T) => T & InstanceType<typeof MyClass>) & typeof MyClass;
    
    const myInstance = new GeneratedClass({ id: 1 });
    
    console.log(myInstance.id, GeneratedClass.someStatic(), myInstance.someMethod());
    
            // inside the class
            public static build(data: T): T & InstanceType<typeof MyClass> {
                return new MyClass(data) as T & InstanceType<typeof MyClass>;
            }
    
    const myInstance = GeneratedClass.build({ id: 1 });
    
    console.log(myInstance.id, GeneratedClass.someStatic(), myInstance.someMethod());
    
    const ClassFactory = <T>() => {
        class MyClass {
            constructor(data: T) {
                for (const key in data) {
                    if (!data.hasOwnProperty(key)) { continue; }
                    (this as any)[key] = data[key];
                }
            }
    
            public static build(data: T): T & InstanceType<typeof MyClass> {
                return new MyClass(data) as T & InstanceType<typeof MyClass>;
            }
    
            public static someStatic() {
                return 2;
            }
    
            public someMethod() {
                return 3;
            }
        }
    
        return MyClass as (new (data: T) => T & InstanceType<typeof MyClass>) & typeof MyClass;
    }
    
    const GeneratedClass = ClassFactory<{ id: number }>();
    
    const myInstance = new GeneratedClass({ id: 1 });
    
    console.log(myInstance.id, GeneratedClass.someStatic(), myInstance.someMethod());
    
    const myBuiltInstance = GeneratedClass.build({ id: 1 });
    
    console.log(myBuiltInstance.id, GeneratedClass.someStatic(), myBuiltInstance.someMethod());