【发布时间】:2019-02-21 14:34:54
【问题描述】:
作为我昨天的question 的后续行动:我现在有一个函数可以根据其参数返回一个类。
function Model<T>(name: string, defaults: () => T) : new(options: Partial<T>) => Pick<T, keyof T> {
return class {
public _symbol = name
protected options: T
constructor (options: Partial<T>) {
this.options = { ...defaults(), ...options }
return new Proxy(this, {
get (target, prop: keyof T) {
return target.options[prop]
}
})
}
} as any
}
type Options {
username: string,
email: string
}
class User extends Model<Options>('user', () => ({
username: getRandomUsername(),
email: getRandomEmail()
}) {
sayHello () : void {
console.log('Hello ' + this.options.username)
}
}
Model 函数接受一个名称参数,该参数将设置到每个实例中,以及一个生成默认值的函数。因此,我创建的每个 new User() 都会有一个随机的用户名和电子邮件,但当我使用 new User({ username: 'John' }) 时,我仍然可以覆盖其中任何一个。
该构造函数 (Pick<T, keyof T>) 的结果类型不再向其添加任何属性,因此当我创建模型时,_symbol 属性对 TypeScript 来说是“丢失”的(这意味着 new User()._symbol 不会' t 编译)。
一种解决方法是让Model 函数的返回类型是这样的:
type ModelClass<T> = Pick<T, keyof T> & { _symbol: string }
这样,new User()._symbol 编译并返回 "user"。但是我不希望 _symbol 成为实例属性,我希望它成为静态类属性。不幸的是,我找不到任何关于如何修改这种新类型ModelClass 以指定具有静态属性的类的信息。有什么办法可以在 TypeScript 中解决这个问题?
【问题讨论】:
标签: typescript