为什么我在这里收到 "wrong type" 错误?
Why am I getting the "wrong type" error here?
我有以下两个 TypeScript classes:
export class AbsenceWithUser {
@jsonProperty(Absence) public readonly absence: Absence;
@jsonProperty(User) public readonly user: User;
constructor(absence: Absence, user: User) {
this.absence = absence;
this.user = user;
}
}
export class Birthday {
@jsonProperty(MomentDateJson) public readonly birthday: moment.Moment;
@jsonProperty(User) public readonly user: User;
constructor(birthday: moment.Moment, user: User) {
this.birthday = birthday;
this.user = user;
}
}
我需要创建一个数组,其中的元素可以是 AbsenceWithUser
或 Birthday
的实例。我使用以下方法执行此操作:
private getAllEvents():(AbsenceWithUser|Birthday)[] {
const absences = this.props.absences as (AbsenceWithUser|Birthday)[];
const birthdays = this.props.birthdays as (AbsenceWithUser|Birthday)[];
return absences.concat(birthdays);
}
但是,如果我使用 getAllEvents
创建一个数组,它的元素不会被识别为 class 的实例。我有以下功能:
private eventToDate(x:AbsenceWithUser | Birthday):Moment {
if (x instanceof AbsenceWithUser) {
return x.absence.endDate;
} else if (x instanceof Birthday) {
return x.birthday;
} else {
throw new Error("Unknown event type, x: " + x);
}
}
以下代码产生错误 "Unknown event type"。
const events = this.getAllEvents();
this.eventToDate(events[0]);
我应该如何更改我的代码才能区分 eventToDate
中的 AbsenceWithUser
和 Birthday
?
注意不需要是instanceof
.
更新 1 (13:27 01.10.2017 MSK):
试图将 getEvents
方法更改为此:
private getAllEvents():(AbsenceWithUser|Birthday)[] {
const absences:(AbsenceWithUser|Birthday) = this.props.absences as (AbsenceWithUser|Birthday)[];
const birthdays:(AbsenceWithUser|Birthday) = this.props.birthdays as (AbsenceWithUser|Birthday)[];
return absences.concat(birthdays);
}
现在我在 WebStorm 中收到类似 Error:(127, 15) TS2322:Type '(AbsenceWithUser | Birthday)[]' is not assignable to type 'AbsenceWithUser | Birthday'.
Type '(AbsenceWithUser | Birthday)[]' is not assignable to type 'Birthday'.
Property 'birthday' is missing in type '(AbsenceWithUser | Birthday)[]'.
的错误。
更新 2 (13:31 01.10.2017 MSK): 我尝试创建一个空数组,然后使用 concat
将缺席和生日数组合并为一个.为此,我创建了以下数组:
const a:(AbsenceWithUser|Birthday) = [];
WebStorm 报告此错误:Error:(127, 15) TS2322:Type 'never[]' is not assignable to type 'AbsenceWithUser | Birthday'. Type 'never[]' is not assignable to type 'Birthday'. Property 'birthday' is missing in type 'never[]'.
我不知道 never[]
类型是从哪里来的。
更新 3 (13:46 01.10.2017 MSK): 修复了 getAllEvents
.
中明显的类型错误
private getAllEvents():(AbsenceWithUser|Birthday)[] {
const absences:(AbsenceWithUser|Birthday)[] = this.props.absences as (AbsenceWithUser|Birthday)[];
const birthdays:(AbsenceWithUser|Birthday)[] = this.props.birthdays as (AbsenceWithUser|Birthday)[];
const allEvents:(AbsenceWithUser|Birthday)[] = absences.concat(birthdays);
return allEvents;
}
更新 4 (14:01 01.10.2017 MSK):
另一次尝试:
export type EventTypes = (AbsenceWithUser|Birthday);
private isEmpty(arr:EventTypes[]):boolean {
return arr.length === 0;
}
private getAllEvents():EventTypes[] {
const absences:EventTypes[] = this.props.absences as EventTypes[];
const birthdays:EventTypes[] = this.props.birthdays as EventTypes[];
const absencesEmpty:boolean = this.isEmpty(absences);
const birthdaysEmpty:boolean = this.isEmpty(birthdays)
if (absencesEmpty && !birthdaysEmpty) {
return birthdays;
} else if (absencesEmpty && birthdaysEmpty) {
return [];
} else if (!absencesEmpty && !birthdaysEmpty) {
return absences.concat(birthdays);
} else if (!absencesEmpty && birthdaysEmpty) {
return absences;
}
return [];
}
更新 5 (15:28 01.10.2017 MSK): 最终版本:
private getAllEvents():EventTypes[] {
const absences:EventTypes[] = this.props.absences.map(absenceJson => {
return new AbsenceWithUser(absenceJson.absence, absenceJson.user);
});
const birthdays:EventTypes[] = this.props.birthdays.map(birthdayJson => {
return new Birthday(birthdayJson.birthday, birthdayJson.user);
});
const absencesEmpty = this.isEmpty(absences);
const birthdaysEmpty = this.isEmpty(birthdays);
if (absencesEmpty && birthdaysEmpty) {
return [];
} else if (absencesEmpty && !birthdaysEmpty) {
return birthdays;
} else if (!absencesEmpty && birthdaysEmpty) {
return absences;
} else {
return absences.concat(birthdays);
}
}
请注意,理论上您可以使用 Object.assign
将反序列化的对象从 JSON 转换为 Typescript class 实例(如果您的环境支持)。
我创建了一个示例,展示了如何将两个特定类型的数组合并为一个可以包含两种类型项目的数组。您可以使用 instanceof
检查类型。
class AbsenceWithUser {
public readonly when: string;
public readonly user: string;
}
class Birthday {
public readonly day: string;
public readonly user: string;
}
class Test {
constructor(){
let absences : AbsenceWithUser[] = [new AbsenceWithUser(), new AbsenceWithUser()]
let birthdays : Birthday[] = [new Birthday(), new Birthday(), new Birthday()]
let combined:(AbsenceWithUser | Birthday)[] = this.mergeArrays(absences, birthdays)
if (combined[0] instanceof Birthday) {
console.log("we have a birthday")
} else {
console.log("we have an absence")
}
}
private mergeArrays(absences: AbsenceWithUser[], birthdays: Birthday[]): (AbsenceWithUser | Birthday)[] {
var allEvents : (AbsenceWithUser | Birthday)[] = [...birthdays].concat(...absences);
return allEvents;
}
}
我有以下两个 TypeScript classes:
export class AbsenceWithUser {
@jsonProperty(Absence) public readonly absence: Absence;
@jsonProperty(User) public readonly user: User;
constructor(absence: Absence, user: User) {
this.absence = absence;
this.user = user;
}
}
export class Birthday {
@jsonProperty(MomentDateJson) public readonly birthday: moment.Moment;
@jsonProperty(User) public readonly user: User;
constructor(birthday: moment.Moment, user: User) {
this.birthday = birthday;
this.user = user;
}
}
我需要创建一个数组,其中的元素可以是 AbsenceWithUser
或 Birthday
的实例。我使用以下方法执行此操作:
private getAllEvents():(AbsenceWithUser|Birthday)[] {
const absences = this.props.absences as (AbsenceWithUser|Birthday)[];
const birthdays = this.props.birthdays as (AbsenceWithUser|Birthday)[];
return absences.concat(birthdays);
}
但是,如果我使用 getAllEvents
创建一个数组,它的元素不会被识别为 class 的实例。我有以下功能:
private eventToDate(x:AbsenceWithUser | Birthday):Moment {
if (x instanceof AbsenceWithUser) {
return x.absence.endDate;
} else if (x instanceof Birthday) {
return x.birthday;
} else {
throw new Error("Unknown event type, x: " + x);
}
}
以下代码产生错误 "Unknown event type"。
const events = this.getAllEvents();
this.eventToDate(events[0]);
我应该如何更改我的代码才能区分 eventToDate
中的 AbsenceWithUser
和 Birthday
?
注意不需要是instanceof
.
更新 1 (13:27 01.10.2017 MSK):
试图将 getEvents
方法更改为此:
private getAllEvents():(AbsenceWithUser|Birthday)[] {
const absences:(AbsenceWithUser|Birthday) = this.props.absences as (AbsenceWithUser|Birthday)[];
const birthdays:(AbsenceWithUser|Birthday) = this.props.birthdays as (AbsenceWithUser|Birthday)[];
return absences.concat(birthdays);
}
现在我在 WebStorm 中收到类似 Error:(127, 15) TS2322:Type '(AbsenceWithUser | Birthday)[]' is not assignable to type 'AbsenceWithUser | Birthday'.
Type '(AbsenceWithUser | Birthday)[]' is not assignable to type 'Birthday'.
Property 'birthday' is missing in type '(AbsenceWithUser | Birthday)[]'.
的错误。
更新 2 (13:31 01.10.2017 MSK): 我尝试创建一个空数组,然后使用 concat
将缺席和生日数组合并为一个.为此,我创建了以下数组:
const a:(AbsenceWithUser|Birthday) = [];
WebStorm 报告此错误:Error:(127, 15) TS2322:Type 'never[]' is not assignable to type 'AbsenceWithUser | Birthday'. Type 'never[]' is not assignable to type 'Birthday'. Property 'birthday' is missing in type 'never[]'.
我不知道 never[]
类型是从哪里来的。
更新 3 (13:46 01.10.2017 MSK): 修复了 getAllEvents
.
private getAllEvents():(AbsenceWithUser|Birthday)[] {
const absences:(AbsenceWithUser|Birthday)[] = this.props.absences as (AbsenceWithUser|Birthday)[];
const birthdays:(AbsenceWithUser|Birthday)[] = this.props.birthdays as (AbsenceWithUser|Birthday)[];
const allEvents:(AbsenceWithUser|Birthday)[] = absences.concat(birthdays);
return allEvents;
}
更新 4 (14:01 01.10.2017 MSK):
另一次尝试:
export type EventTypes = (AbsenceWithUser|Birthday);
private isEmpty(arr:EventTypes[]):boolean {
return arr.length === 0;
}
private getAllEvents():EventTypes[] {
const absences:EventTypes[] = this.props.absences as EventTypes[];
const birthdays:EventTypes[] = this.props.birthdays as EventTypes[];
const absencesEmpty:boolean = this.isEmpty(absences);
const birthdaysEmpty:boolean = this.isEmpty(birthdays)
if (absencesEmpty && !birthdaysEmpty) {
return birthdays;
} else if (absencesEmpty && birthdaysEmpty) {
return [];
} else if (!absencesEmpty && !birthdaysEmpty) {
return absences.concat(birthdays);
} else if (!absencesEmpty && birthdaysEmpty) {
return absences;
}
return [];
}
更新 5 (15:28 01.10.2017 MSK): 最终版本:
private getAllEvents():EventTypes[] {
const absences:EventTypes[] = this.props.absences.map(absenceJson => {
return new AbsenceWithUser(absenceJson.absence, absenceJson.user);
});
const birthdays:EventTypes[] = this.props.birthdays.map(birthdayJson => {
return new Birthday(birthdayJson.birthday, birthdayJson.user);
});
const absencesEmpty = this.isEmpty(absences);
const birthdaysEmpty = this.isEmpty(birthdays);
if (absencesEmpty && birthdaysEmpty) {
return [];
} else if (absencesEmpty && !birthdaysEmpty) {
return birthdays;
} else if (!absencesEmpty && birthdaysEmpty) {
return absences;
} else {
return absences.concat(birthdays);
}
}
请注意,理论上您可以使用 Object.assign
将反序列化的对象从 JSON 转换为 Typescript class 实例(如果您的环境支持)。
我创建了一个示例,展示了如何将两个特定类型的数组合并为一个可以包含两种类型项目的数组。您可以使用 instanceof
检查类型。
class AbsenceWithUser {
public readonly when: string;
public readonly user: string;
}
class Birthday {
public readonly day: string;
public readonly user: string;
}
class Test {
constructor(){
let absences : AbsenceWithUser[] = [new AbsenceWithUser(), new AbsenceWithUser()]
let birthdays : Birthday[] = [new Birthday(), new Birthday(), new Birthday()]
let combined:(AbsenceWithUser | Birthday)[] = this.mergeArrays(absences, birthdays)
if (combined[0] instanceof Birthday) {
console.log("we have a birthday")
} else {
console.log("we have an absence")
}
}
private mergeArrays(absences: AbsenceWithUser[], birthdays: Birthday[]): (AbsenceWithUser | Birthday)[] {
var allEvents : (AbsenceWithUser | Birthday)[] = [...birthdays].concat(...absences);
return allEvents;
}
}