从静态上下文在TypeScript上创建新类实例时如何设置类型并避免循环类型依赖关系
在解决这个问题时,我花了一天的时间尝试了各种黑客和技术,现在我要求社区分享一些知识 基本上有一个抽象模型和存储库类,它们由其他简单的具体类扩展。没什么特别的 下面提供的代码在编译时100%适用于我,但在类型方面有两个问题:从静态上下文在TypeScript上创建新类实例时如何设置类型并避免循环类型依赖关系,typescript,inheritance,constructor,typescript-typings,Typescript,Inheritance,Constructor,Typescript Typings,在解决这个问题时,我花了一天的时间尝试了各种黑客和技术,现在我要求社区分享一些知识 基本上有一个抽象模型和存储库类,它们由其他简单的具体类扩展。没什么特别的 下面提供的代码在编译时100%适用于我,但在类型方面有两个问题: 泛型中的循环类型依赖项(泛型类型“存储库”需要1个类型参数)。) 动态构造函数(类型为“typeof Model”的参数不能分配给类型为“new”(…args:unknown[])=>Model的参数)的问题你能解决这个问题吗?我在typescript和generics方面
- 泛型中的循环类型依赖项(
)泛型类型“存储库”需要1个类型参数)。
- 动态构造函数(
类型为“typeof Model”的参数不能分配给类型为“new”(…args:unknown[])=>Model的参数)的问题你能解决这个问题吗?我在typescript和generics方面也有类似的问题。你能解决这个问题吗?我在typescript和generics方面也有类似的问题
// @see https://github.com/Microsoft/TypeScript/wiki/FAQ#why-cant-i-write-typeof-t-new-t-or-instanceof-t-in-my-generic-function function create<T>(ctor: { new(...args: unknown[]): T }, ...args: unknown[]) { return new ctor(...args); } // Some real-world example, see the problematic classes below class Collection<T extends Model> { constructor(public items: T[]) { } all() { return this.items; } get(index: number) { return this.items[index]; } } // Issue #1. In fact, <any> is not what I want here, but a relevant type abstract class Model<R extends Repository<any>> { exists = false; name?: string; constructor(protected repository: R, args: unknown) { Object.assign(this, args); } markExists() { this.exists = true; return this; } } abstract class Repository<M extends Model<any>> { public model = Model; public fromArray(array: unknown[]) { const mapped = array.map((i) => { // Issue #2 const m = create(this.model, this, i); m.markExists(); return m; }) as M[]; return new Collection<M>(mapped); } public static fromArray<M>(array: unknown[]) { // Another case of issue #2 return create(this).fromArray(array); } } class Client extends Model<Repository<any>> { domain = 'clients'; } class ClientRepository extends Repository<Client> { domain = 'clients'; } const array = [{ name: 'John' }, { name: 'Samantha' }]; const hydratedClients = ClientRepository.fromArray(array); console.log(hydratedClients.get(0).name); // John console.log(hydratedClients.get(1).name) // Samantha