Typescript编译器显示的类型与实际不同



我正在为我的宠物项目开发自己的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可能会推断基类,因为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);
}

我已经找到了这个问题的理想解决方案。因此,这里有新的代码:

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;
}
}

在显式定义了this之后,通过创建一个新的自己的类型,TypeScript正确地定义了type of week变量。下面是工作代码的源代码:使用TypeScript从基类中的静态方法实例化子类TypeScript:继承类的静态方法的自引用返回类型

最新更新