我有一个用普通Javascript编写的系统,其中可以使用类型作为方法覆盖定义模型,并在数据进入时进行转换,但是想要纯粹基于赋值获得typescript的好处(而不是实例化,或者至少不那么重要)。
typescript应该是配置字典/纯对象的产品。是否有一种动态定义以下模式的方法?我确实看到了一些定义字典的示例,但我想对任何模型执行此操作(这仍需要代码复制)
我看到可能可以制作一个typescript插件或进行接口代码生成。在四处查找之后,我没有看到任何类似的答案。只是想知道是否有人对完成最佳方式有任何想法或者它根本不可能。
从属性动态生成类型?
用户使用模型.模型是我们的基本模型类,使用公共属性和类型来进行转换并设置诸如readonly或any之类的东西。需要添加typescript,但基本上是从真相源易于推导出自己的重复。
export class User extends Model {
// can i automate the process of generating this below from
// definePublicAttributes
firstName?: string;
lastName?: string;
email?: string;
state?: string;
countryCode?: string;
lookupCreditBalance?: number;
creditTime?: Date;
// this will pull in andd assign to the instance when data dict
// is passed..can this be read or provided some way
definePublicAttributes(any) {
return {
first_name: String,
last_name: String,
email: String,
state: String,
country_code: String,
lookup_credit_balance: Number,
create_time: Date,
is_anonymous: any.readOnly,
profile_url: any.readOnly,
}
}
为了提供一个完整的最小可重现示例,请参见我正在进行的虚构简化版本。
(附注:请注意,除了初始转换之外,模型系统在应用程序的整个生命周期中用于其他事情,例如更改,但出于简单起见而省略)
最小可重现示例
两个模型(Pet
和Person
)扩展基本Model
,从嵌套的纯对象和模型类型定义实例化。我只想让TypeScript在编辑时防止错误的类型分配和文档,但可能不需要显式编写类型定义,而是从属性/方法/源(如get publicAttributes()
)获取它。
class Model {
get publicAttributes() {
return {}
}
cast(value, type=null) {
if (type === Date) {
return new Date(value);
} else if (type === Number) {
return Number(value);
} else if (type === String) {
return value.toString();
} else if (Model.isModel(type)) {
const model = new type(value);
return model;
} else if (Array.isArray(type)) {
return value.map((item) => {
return this.cast(item, type[0]);
});
} else if (typeof type === 'function') {
// if function, invoke and pass in
return this.cast(value, type(value))
}
return value;
}
static isModel(val) {
return (
val?.prototype instanceof Model ||
val?.constructor?.prototype instanceof Model
);
}
constructor(data={}) {
for (let [key, value] of Object.entries(data)) {
this[key] = this.cast(value, this.publicAttributes[key] || null);
}
}
}
class Pet extends Model {
// can below be progammatically derived (?)
name?: string
type?: string
get publicAttributes() {
return {
name: String,
type: String,
}
}
}
class Person extends Model {
// can below be progammatically derived (?)
joined?: Date
name?: string
age?: number
skills?: Array<string>
locale?: any
pets?: Array<Pet>
get publicAttributes() {
return {
joined: Date, // primative
name: String, // primative
age: Number, // primative
skills: [String], // primative arr
locale: (v) => v === 'vacation' ? null : String, // derived type via fn
pets: [Pet], // model arr
}
}
}
const bill = new Person({
joined: '2021-02-10',
name: 'bill',
age: '26',
skills: ['python', 'dogwalking', 500],
locale: 'vacation',
pets: [
{
name: 'rufus',
type: 'dog',
},
]
});
console.log(bill);
<T>
is-it-possible-to-auto-generate-class-properties-from-its-generic-type,并且T
将作为接口definePublicAttributes
的定义 :-? - Mara BlackpublicAttributes: T } & Model & Partial<_MFA<T>>;
,或者我目前可能对 TypeScript 还不太熟悉哈哈。 - c.m