Typescript泛型类型检查失败 //RepositoryBase.ts 导出类型FieldsMapping={readonly[k in keyof Required]:string}; 导出抽象类RepositoryBase{ 受保护的摘要只读列:字段映射; } //UsersRepository.ts 从“/RepositoryBase”导入{FieldsMapping,RepositoryBase}; 界面用户{ 名字:字符串; lastName:string; 电子邮件?:字符串; } 导出类UsersRepository扩展了RepositoryBase{ 受保护的只读列={ 名字:“名字”, 姓氏:“姓氏”, 电子邮件:“电子邮件”, 额外:“非现有列”, }; }
Typescript泛型类型检查失败 //RepositoryBase.ts 导出类型FieldsMapping={readonly[k in keyof Required]:string}; 导出抽象类RepositoryBase{ 受保护的摘要只读列:字段映射; } //UsersRepository.ts 从“/RepositoryBase”导入{FieldsMapping,RepositoryBase}; 界面用户{ 名字:字符串; lastName:string; 电子邮件?:字符串; } 导出类UsersRepository扩展了RepositoryBase{ 受保护的只读列={ 名字:“名字”, 姓氏:“姓氏”, 电子邮件:“电子邮件”, 额外:“非现有列”, }; },typescript,generics,Typescript,Generics,UsersRepository中列的声明不会给出任何编译错误,即使User界面上不存在extra键 如果我将类型添加到UserRepository中的列中,例如:COLUMNS:FieldsMapping,则会引发错误 我不想在继承RepositoryBase的每个类上重新声明类型。你知道为什么会这样吗?可能是由于摘要?或者可能是由于tsconfig.json中的某些配置造成的?知道怎么解决吗?const userLike={ 名字:'', 姓氏:“”, 电子邮件:“”, az:' }; con
UsersRepository
中列的声明不会给出任何编译错误,即使User
界面上不存在extra
键
如果我将类型添加到UserRepository
中的列中,例如:COLUMNS:FieldsMapping
,则会引发错误
我不想在继承RepositoryBase
的每个类上重新声明类型。你知道为什么会这样吗?可能是由于摘要
?或者可能是由于tsconfig.json
中的某些配置造成的?知道怎么解决吗?const userLike={
名字:'',
姓氏:“”,
电子邮件:“”,
az:'
};
const user:user=userLike;
Typescript允许这种“灵活”的分配。他对申报更严格
关于这个问题有一个有趣的建议:当您使用扩展接口或类时,您可以通过添加新属性或缩小现有属性来缩小子接口/子类。因此,在TypeScript中,UserRepository
的COLUMNS
属性比RepositoryBase
的COLUMNS
属性更具体是完全可以接受的。这就是扩展
的明确目的
如果您选择将列
属性
用户存储库
的类型注释为记录
(相当于您的字段映射
),并在分配中使用新的对象文字,您将获得并标记额外的属性
如果这对你有用的话,你应该去做。。。它有点多余(您必须在RepositoryBase
的泛型参数和列
属性的注释中写入User
),但相当干净
否则,我没有任何很好的修复方法,主要是因为protected
属性很难通过编程进行操作。(例如,UserRepository的键
不包括列
,因此UserRepository[“列”]
无效)
我想我能得到的最接近的方法是一个名为strictColumns()
的通用方法,它只接受没有已知额外属性的字段映射。。。该方法将只返回其输入,因此您可以使用它初始化列
属性:
// RepositoryBase.ts
export type FieldsMapping<T> = { readonly [k in keyof Required<T>]: string };
export abstract class RepositoryBase<T> {
protected abstract readonly COLUMNS: FieldsMapping<T>;
}
// UsersRepository.ts
import { FieldsMapping, RepositoryBase } from './RepositoryBase';
interface User {
firstName: string;
lastName: string;
email?: string;
}
export class UsersRepository extends RepositoryBase<User> {
protected readonly COLUMNS = {
firstName: 'first_name',
lastName: 'last_name',
email: 'email',
extra: 'non_existing_column',
};
}
抽象类RepositoryBase{
受保护的摘要只读列:记录;
狭窄柱<
U扩展{[K in keyof T | keyof U]:K扩展keyof T?string:never}
>(u:u){
返回u;
}
}
像这样:
abstract class RepositoryBase<T> {
protected abstract readonly COLUMNS: Record<keyof T, string>;
strictColumns<
U extends { [K in keyof T | keyof U]: K extends keyof T ? string : never }
>(u: U) {
return u;
}
}
class UsersRepository扩展了RepositoryBase{
受保护的只读列=this.strictColumns({
名字:“名字”,
姓氏:“姓氏”,
电子邮件:“电子邮件”
});
}//好的
类BadUsersRepository扩展了RepositoryBase{
受保护的只读列=this.strictColumns({
名字:“名字”,
姓氏:“姓氏”,
电子邮件:“电子邮件”,
额外:“额外”//error!字符串不可分配给never
});
}
这是可行的,但增加的复杂性可能不值得稍微减少冗余。哦,好吧
希望有帮助。祝你好运
class UsersRepository extends RepositoryBase<User> {
protected readonly COLUMNS = this.strictColumns({
firstName: "first_name",
lastName: "last_name",
email: "email"
});
} // okay
class BadUsersRepository extends RepositoryBase<User> {
protected readonly COLUMNS = this.strictColumns({
firstName: "first_name",
lastName: "last_name",
email: "email",
extra: "extra" // error! string is not assignable to never
});
}