【问题标题】:Typescript compiler shows different type from actualTypescript 编译器显示与实际不同的类型
【发布时间】:2021-09-08 07:52:55
【问题描述】:

我正在为我的宠物项目为 Postgres DB 开发自己的 ORM。但我面临的问题是打字稿认为存在与我实际得到的类型不同的类型。代码如下:

//model.ts
export class TestModel {
  
  static tableName: string;
  constructor(data:any) {
    
  }

  public static async findById(id: number) {
    const client = await pool.connect();
    const result: QueryResult<any> = await client.query(
      `select * from public."${this.tableName}" where id = ${id}`
    );
    const results = result ? result.rows : null;
    client.release();
    if (!results) return null;
    return new this(results[0]);
  }

}

export class TestWeekModel extends TestModel {
  static tableName = 'Week';
  id: any;
  current_week: any;
  
  constructor(data: any) {
    super(data);
    this.id = data.id;
    this.current_week = data.current_week;
  }
}

//test.ts 
import { TestModel, TestWeekModel } from "./database/model";


async function test() {
    const week = await TestWeekModel.findById(1);
    console.log(week);
}

test();

实际输出为:TestWeekModel { id: 1, current_week: 2 }

但是 typescript 说变量“week”的类型是“const week: TestModel | null”。为什么 typescript 认为那周是 TestModel 类型而不是 TestWeekModel?如何获得所需的 TestWeekModel 类型?

【问题讨论】:

    标签: typescript types


    【解决方案1】:

    TypeScript 可能会推断基类,因为在那里定义了 findById()。一个简单的解决方法是使用类型断言

    const week = await TestWeekModel.findById(1) as TestWeekModel;

    另一种选择是让方法返回结果,并在赋值时实例化新类。

    // TestModel...
    if (!results) return null;
    return results[0];
    // ..
    
    async function test() {
      const result = await TestWeekModel.findById(1);
      const week = new TestWeekModel(result);
      console.log(week);
    }
    

    【讨论】:

    • 哦,非常感谢。那么没有其他选择可以得到想要的结果吗?第一个解决方案很好,但我想在类中的某个地方进行,但不要覆盖子类中的方法或类型。
    【解决方案2】:

    我已经找到了问题的所需解决方案。所以,这里有新代码:

    type Constructor<T> = { new (data: any): T, tableName: string }
    export class TestModel {
      
      static tableName: string;
      constructor(data:any) {
        
      }
    
      public static async findById<T>(this: Constructor<T>,id: number){
        const client = await pool.connect();
        const result: QueryResult<any> = await client.query(
          `select * from public."${this.tableName}" where id = ${id}`
        );
        const results = result ? result.rows : null;
        client.release();
        if (!results) return null;
        return new this(results[0]);
      }
    
    }
    
    export class TestWeekModel extends TestModel {
      static tableName = 'Week';
      id: any;
      current_week: any;
    
      
      constructor(data: any) {
        super(data);
        this.id = data.id;
        this.current_week = data.current_week;
      }
    }
    

    在明确定义这个之后,通过创建一个新的自己的类型,TypeScript 正确地定义了 week 变量的类型。 这是工作代码的来源: Instantiating child class from a static method in base class, using TypeScript TypeScript: self-referencing return type for static methods in inheriting classes

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      相关资源
      最近更新 更多