在TypeScript中,可以使用带有访问修饰符的参数的构造函数创建一个类,并自动在类字段中转换这些参数。
class Item {
constructor(
public id: number,
public updatedAt: number,
public createdAt: number,
) {}
}
const item = new Item(1, 1, 1);
item.id // 1
我想知道是否有办法在对象中传递所有这些参数
class Item {
constructor({
public id: number,
public updatedAt: number,
public createdAt: number,
}) {}
}
const item = new Item({ id: 1, updatedAt: 1, createdAt: 1 });
item.id // 1
这可能吗?有可能吗?
是否有类似的工作方法?
答案 0 :(得分:9)
最简单的方法是声明类中的字段并使用映射类型作为参数,然后使用Object.assign
将字段分配给this
。我们有几个选项可供使用的映射类型:
<强> Partial<T>
强>
Type将包含该类的所有成员(字段和方法),但所有成员都是可选的。这里的缺点是我们无法创建所需的某些字段,调用者可能会覆盖方法
class Item {
public id: number;
public updatedAt: number;
public createdAt: number;
constructor(data: Partial<Item>) {
Object.assign(this, data);
}
method() {}
}
//Works
const item = new Item({ id: 1, updatedAt: 1, createdAt: 1 });
//This also works unfortunately
const item2 = new Item({ id: 1, method() { console.log('overriden from param !')} });
<强> Pick<T, K>
强>
这种映射类型允许我们通过指定T
的键的几个字符串文字类型的并集来从T
中选择一些属性。优点是Pick
将继承该类是否需要来自类中的原始声明(因此可能需要某些字段和其他可选项),并且由于我们指定了我们选择的成员,因此我们可以省略方法。缺点是我们必须写两次属性名称(一次在类中,一次在Pick中):
class Item {
public id: number;
public updatedAt?: number;
public createdAt?: number;
constructor(data: Pick<Item, "id" | "updatedAt" | "createdAt">) {
Object.assign(this, data);
}
method() {}
}
const item = new Item({ id: 1 }); //id is required others fields are not
const item2 = new Item({ id: 1, method() {} }); // error method is not allowed
删除方法的自定义映射类型
第三个选项是创建一个类似于Pick
的类型,它包括所有类字段,但不包括自动的方法。我们可以使用条件类型在Typescript 2.8中执行此操作(在撰写本文时尚未发布,但应在2018年3月发布,您可以通过npm install -g typescript@next
立即获取)。这具有Pick
的优点,而无需再次指定字段名称:
type NonMethodKeys<T> = ({[P in keyof T]: T[P] extends Function ? never : P } & { [x: string]: never })[keyof T];
type RemoveMethods<T> = Pick<T, NonMethodKeys<T>>;
class Item {
public id: number;
public updatedAt?: number;
public createdAt?: number;
constructor(data: RemoveMethods<Item>) { // No need to specify field names again
Object.assign(this, data);
}
method() {}
}
const item = new Item({ id: 1 }); //id is required others fields are not
const item2 = new Item({ id: 1, method() {} }); // error method is not allowed
答案 1 :(得分:2)
您可以通过创建界面来实现类似的行为:
interface IProps {
id: number;
updatedAt: number;
createdAt: number;
}
class Item {
constructor(public props: IProps) {}
}
const item = new Item({ id: 1, updatedAt: 1, createdAt: 1 });
console.log(item.props.id);
答案 2 :(得分:0)
对象解构是最佳选择
class Item {
public id: number;
public updatedAt: number;
public createdAt: number;
constructor({
id,
updatedAt,
createdAt,
}: { id: number, updatedAt: number, createdAt: number }) {
this.id = id;
this.updatedAt = updatedAt;
this.createdAt = createdAt;
}
}
var item = new Item({ id: 1, updatedAt: 3, createdAt: 4 });
console.log(item.id);