打字稿可选 属性 带有 getter
typescript optional property with a getter
这是一个简化的例子:
class PersonParms{
name:string;
lastName:string;
age?:number;
get fullName(){return this.name + " " + this.lastName;}
}
class Person{
constructor(prms:PersonParms){
}
}
new Person({name:'John',lastName:'Doe'}) // ts error: Property 'fullName' is missing in type '{ name: string; lastName: string; }'.
想法是将文字对象作为 PersonParms 的 intizalizer 传递,但是有了 getter,您既不能声明 getter 可选,也不能将 属性 添加到对象文字。还有其他方法可以实现吗?
Is there another way to achieve it?
以下是我的做法:
class Person {
constructor(public config: { name: string, lastName: string }) {}
age?: number;
get fullName() { return this.config.name + " " + this.config.lastName; }
}
new Person({ name: 'John', lastName: 'Doe' })
非常有趣。我认为,你应该 report an issue 到 TypeScript,因为方法可以是可选的(见下文),但 属性 吸气剂不是。这很奇怪.. 作为一种解决方法,我可以建议两种变体。一个不错的:
class PersonParms {
name:string;
lastName:string;
age?: number;
getFullName?() {return this.name + " "+this.lastName;}
}
还有第二个,这是 hacky,因为我们在传递给构造函数时将所有属性设为可选。
class PersonParms {
name:string;
lastName:string;
age?: number;
get fullName(){return this.name + " "+this.lastName;}
}
class Person{
constructor(prms: Partial<PersonParms>){
}
}
我找到了适合我的解决方案:
class Person {
name?:string;
lastName?:string;
age?: number;
fullName?:string;
constructor(public config: { name: string, lastName: string }) {
Object.defineProperty(this,'fullName',{
get(){return this.name + " " + this.lastName;}
});
}
class PersonParms {
name: string;
lastName: string;
age?: number;
fullName?: string = this.name + ' ' + this.lastName;
}
class Person {
constructor(prms: PersonParms) {
}
}
new Person({ name: 'John', lastName: 'Doe' });
class PersonParms {
name: string;
lastName: string;
age?: number;
getFullName?(): string | null { return this.name + ' ' + this.lastName; }
}
class Person {
constructor(prms: PersonParms) {
}
}
new Person({ name: 'John', lastName: 'Doe' });
如果您创建一个新的 PersonParms 实例,那么错误将消失。
class PersonParms{
name:string;
lastName:string;
age?:number;
get fullName(){return this.name + " "+this.lastName;}
}
class Person{
constructor(prms:PersonParms){
}
}
const personParams = new PersonParms();
personParams.name = 'John';
personParams.lastName = 'John';
new Person(personParams) // No error because this is an instance of PersonParams
我不确定 where/how 你是否使用 PersonParms.fullname 但在你的情况下我会使用这个:
interface PersonParms{
name:string;
lastName:string;
age?:number;
}
class Person implements PersonParms{
name: string;
lastName: string;
age?:number
constructor(prms: PersonParms) {
this.name = prms.name;
this.lastName = prms.lastName;
this.age = prms.age;
}
get fullName(){return this.name + " "+this.lastName;}
}
const person = new Person({ name: 'John', lastName: 'Doe' });
console.log(person.fullName); // John Doe
截至 2020 年 4 月,没有 方法来实现这一点。
对此有一个不确定的 PR:
https://github.com/microsoft/TypeScript/pull/16344
此处介绍了通过界面提出的解决方案:
https://github.com/microsoft/TypeScript/pull/16344
就我个人而言,该解决方案不符合我的需求,我宁愿将 属性 声明为私有。
希望我们以后能有更好的运气。
如果转换对象,这将防止编译时错误。
export class IndividualModel {
constructor(individual: IndividualModel = null) {
if (individual) {
this.individualKey = individual.individualKey;
this.firstName = individual.firstName;
this.lastName = individual.lastName;
}
}
individualKey: string;
firstName?: string;
lastName?: string;
get fullName(): string {
return `${this.lastName}, ${this.firstName}`;
}
}
const individual = new IndividualModel(<IndividualModel>{ individualKey: 'some-key' });
请记住,可选是一个类型概念。 getter 是一个实现。实现可以 return 可选类型。在实现带有可选只读 属性 接口的 class 中,class 可能会离开 getter。查看此答案 get and set in TypeScript
这是一个简化的例子:
class PersonParms{
name:string;
lastName:string;
age?:number;
get fullName(){return this.name + " " + this.lastName;}
}
class Person{
constructor(prms:PersonParms){
}
}
new Person({name:'John',lastName:'Doe'}) // ts error: Property 'fullName' is missing in type '{ name: string; lastName: string; }'.
想法是将文字对象作为 PersonParms 的 intizalizer 传递,但是有了 getter,您既不能声明 getter 可选,也不能将 属性 添加到对象文字。还有其他方法可以实现吗?
Is there another way to achieve it?
以下是我的做法:
class Person {
constructor(public config: { name: string, lastName: string }) {}
age?: number;
get fullName() { return this.config.name + " " + this.config.lastName; }
}
new Person({ name: 'John', lastName: 'Doe' })
非常有趣。我认为,你应该 report an issue 到 TypeScript,因为方法可以是可选的(见下文),但 属性 吸气剂不是。这很奇怪.. 作为一种解决方法,我可以建议两种变体。一个不错的:
class PersonParms {
name:string;
lastName:string;
age?: number;
getFullName?() {return this.name + " "+this.lastName;}
}
还有第二个,这是 hacky,因为我们在传递给构造函数时将所有属性设为可选。
class PersonParms {
name:string;
lastName:string;
age?: number;
get fullName(){return this.name + " "+this.lastName;}
}
class Person{
constructor(prms: Partial<PersonParms>){
}
}
我找到了适合我的解决方案:
class Person {
name?:string;
lastName?:string;
age?: number;
fullName?:string;
constructor(public config: { name: string, lastName: string }) {
Object.defineProperty(this,'fullName',{
get(){return this.name + " " + this.lastName;}
});
}
class PersonParms {
name: string;
lastName: string;
age?: number;
fullName?: string = this.name + ' ' + this.lastName;
}
class Person {
constructor(prms: PersonParms) {
}
}
new Person({ name: 'John', lastName: 'Doe' });
class PersonParms {
name: string;
lastName: string;
age?: number;
getFullName?(): string | null { return this.name + ' ' + this.lastName; }
}
class Person {
constructor(prms: PersonParms) {
}
}
new Person({ name: 'John', lastName: 'Doe' });
如果您创建一个新的 PersonParms 实例,那么错误将消失。
class PersonParms{
name:string;
lastName:string;
age?:number;
get fullName(){return this.name + " "+this.lastName;}
}
class Person{
constructor(prms:PersonParms){
}
}
const personParams = new PersonParms();
personParams.name = 'John';
personParams.lastName = 'John';
new Person(personParams) // No error because this is an instance of PersonParams
我不确定 where/how 你是否使用 PersonParms.fullname 但在你的情况下我会使用这个:
interface PersonParms{
name:string;
lastName:string;
age?:number;
}
class Person implements PersonParms{
name: string;
lastName: string;
age?:number
constructor(prms: PersonParms) {
this.name = prms.name;
this.lastName = prms.lastName;
this.age = prms.age;
}
get fullName(){return this.name + " "+this.lastName;}
}
const person = new Person({ name: 'John', lastName: 'Doe' });
console.log(person.fullName); // John Doe
截至 2020 年 4 月,没有 方法来实现这一点。
对此有一个不确定的 PR: https://github.com/microsoft/TypeScript/pull/16344
此处介绍了通过界面提出的解决方案: https://github.com/microsoft/TypeScript/pull/16344
就我个人而言,该解决方案不符合我的需求,我宁愿将 属性 声明为私有。
希望我们以后能有更好的运气。
如果转换对象,这将防止编译时错误。
export class IndividualModel {
constructor(individual: IndividualModel = null) {
if (individual) {
this.individualKey = individual.individualKey;
this.firstName = individual.firstName;
this.lastName = individual.lastName;
}
}
individualKey: string;
firstName?: string;
lastName?: string;
get fullName(): string {
return `${this.lastName}, ${this.firstName}`;
}
}
const individual = new IndividualModel(<IndividualModel>{ individualKey: 'some-key' });
请记住,可选是一个类型概念。 getter 是一个实现。实现可以 return 可选类型。在实现带有可选只读 属性 接口的 class 中,class 可能会离开 getter。查看此答案 get and set in TypeScript