TypeScript定义泛型View类时如何正确声明泛型Model属性类型
TypeScript 嵌套泛型类的类型定义方案
避开Model<any>的写法有两种更严谨的实现,根据业务场景选择即可:
方案1:双泛型参数(推荐,类型完全安全)
给View增加第二个泛型参数,专门对应Model包裹的data类型,全程不会丢失类型信息,TS可以自动完成类型推导,不需要手动标注类型。
class Model<T> { constructor(public data: T) {} } // 新增TData泛型,约束TModel必须是承载TData类型的Model子类 class View<TData, TModel extends Model<TData>> { constructor(public model: TModel) {} // 内部访问model.data时可以拿到完整的类型提示 getData(): TData { return this.model.data; } } // 使用示例 interface UserInfo { id: number; username: string; } const userModel = new Model<UserInfo>({ id: 1, username: "admin" }); // TS自动推导泛型参数,不需要手动写View<UserInfo, Model<UserInfo>> const userView = new View(userModel); const data = userView.getData(); // 自动识别data为UserInfo类型,有完整属性提示
方案2:用unknown替代any(适合不需要操作data内部结构的场景)
如果View只需要约束传入值是Model实例,本身不会访问model.data的具体属性,不需要感知data的类型,可以用unknown作为类型参数,比any的类型安全性高很多:
class View<T extends Model<unknown>> { constructor(public model: T) {} }
和
any的区别:unknown是类型安全的顶层类型,如果后续要访问model.data的属性,必须先做类型收窄/校验,TS不会像对待any一样放任任意非法属性访问,能避免隐式的类型错误。
选型建议
- 如果View内部需要读取、操作
model.data的字段,优先选双泛型方案,全程无类型断言,类型提示完整 - 如果View仅透传Model实例、不操作data内部结构,选
Model<unknown>的写法即可,比any更严谨
内容的提问来源于stack exchange,提问作者Archsx
相关产品推荐
相关产品推荐

