通过泛型找不到扩展类的属性

时间:2019-04-10 16:59:47

标签: typescript

已更新:

我的意图是制作一个可用作Base Model的{​​{1}}的抽象类。静态方法ORMmethod类似,应自行创建实例...

这就是我的想法(在类定义中必须使用通用的“ T”,以便在构造函数参数上进行键入):

find an instance of that model

以下是建议的内容(没有通用名称):

abstract class Model<T extends Model<T>> {
  static property;

  static method<T extends Model<T>>(this: (new () => T)): T {
    console.log(this.property); // TS2339: Property 'property' does not exist on type 'new () => T'

    return new this();
  }

  constructor(item?: Partial<T>) {
    Object.assign(this, item);
  }
}

class User extends Model<User> {
  email: string;
}

const user = User.method();
user.email = 'foo';

原始问题2019-04-10

我有以下一段代码:

abstract class Model1 {
  static property;

  static method() {
    console.log(this.property);

    return new this(); // TS2511: Cannot create an instance of an abstract class
  }

  constructor(item?) { // No clues on the properties of "item"
    Object.assign(this, item);
  }
}

class User1 extends Model1 {
  email: string;
}

const user1 = User1.method();
user1.email = 'foo'; // TS2339: Property 'email' does not exist on type Model1

但是当我尝试运行它时:class Model<T extends Model<T>> { static property; static method<T extends Model<T>>(this: new () => T) { console.log(this.property); } }

识别属性的唯一方法是在方法签名中添加Property 'property' does not exist on type 'new () => T'. (2339)

& typeof Model

但是以这种方式class Model<T extends Model<T>> { static property; static method<T extends Model<T>>(this: (new () => T) & typeof Model) { console.log(this.property); } } 也可以是this的子集,因此返回类似T的内容与返回类型new this()不兼容... < / p>

任何想法?

非常感谢

1 个答案:

答案 0 :(得分:0)

根据OP更新进行编辑

这里发生两件事

  1. 继承自抽象类
  2. 在调用this时推断User.method()的类型
abstract class Model1 {
    static property: boolean = true;

    static method<T>(this: T): T extends new () => infer R ? R : any {
        console.log(this.property); // error, but ignore it, 

        // From this point on, 
        // We should use the type-casted `SubClass` instead of`this`

        // Personally prefer type-cast to `any`
        // Because both `Dog` and `User` can `extends Model1`
        // There's no way to know in advance
        const SubClass = this as any;

        // However, if you really need to see something about `Model1`
        // const SubClass = this as any as (typeof Model1);

        console.log(SubClass.property) // good

        // Since you do understand what you're doing
        // it's fine to simply ts-ignore the warning
        // @ts-ignore
        return new SubClass()

        // Final word, because you've declared full `method()` signature
        // ts is not inferring type of return value from function body
        // so we're good.
    }

    // also check the instance side
    inheritedProperty: number;
}


class User extends Model1 {
    email: string;
}

// both static side and instance side members are all inherited
// and the types are correct
const user = User.method();
user.inheritedProperty = 1; // good
user.email = 'foo'; // good
User.property = 101 // error

还是,我想提请注意以下事实:类的静态方面与类本身没有多大关系。我在原始答案中发布的链接值得阅读,以完全理解该概念。


原始答案:

在足够的条件下(我猜)您想做什么?

class Model {
    static property;

    static method(this: typeof Model) {
        console.log(this.property);
    }
}

还有参考文献,这里是typescript handbook的引文:

  

[...]类的类型有两个方面:静态方面和实例方面。泛型类仅在实例方面是泛型,而在静态方面是泛型,因此在使用类时,静态成员不能使用类的type参数。