我正在为我的宠物项目开发自己的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:继承类的静态方法的自引用返回类型