2017-10-01 16 views
0

私は2つの活字体のクラス次き:ここで「間違ったタイプ」のエラーが表示されるのはなぜですか?

私は配列を作成する必要が
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のいずれかのインスタンスにできます。私はgetAllEventsを使用してアレイを作成する場合は、その要素は、いずれかのクラスのインスタンスとして認識されていない

private getAllEvents():(AbsenceWithUser|Birthday)[] { 
    const absences = this.props.absences as (AbsenceWithUser|Birthday)[]; 
    const birthdays = this.props.birthdays as (AbsenceWithUser|Birthday)[]; 
    return absences.concat(birthdays); 
} 

:私はこの次のメソッドを使用してください。私は次の関数を持っています:

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]); 

私はeventToDateAbsenceWithUserBirthdayを区別できるように、どのように私は私のコードを変更する必要がありますか?

instanceofである必要はありません。

アップデート1(午後01時27分2017年1月10日MSK):

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)[]'.のようなエラーを取得しています:

はこれにgetEvents方法を変更しようとしました。

アップデート2(13時31分2017年1月10日MSK):は、私は1つに不在と誕生日アレイをマージする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(午後02時01 2017年1月10日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 2017年1月10日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クラスのインスタンスに変換することができます(環境がサポートしている場合)。

+1

私はTSに非常に新しいんだけど、あなたは次のように定数を入力してみてください可能性があります。Const欠席(AbsenceWithUser |誕生日)[] =のthis.props.absences。 厳密な型付き言語では、一般に、 "as"を使用してベクトル内のセット全体をキャストすることはできません...最初に定義する必要があります...しかし、私はまだTS newbですので、異なって(もしそうなら)... – joshstrike

+0

@joshstrikeあなたのコメントをありがとう。 –

+0

@joshstrike非常に奇妙です - '(AbsenceWithUser | Birthday)'タイプの**空**配列を作成しても動作しません(アップデート2を参照)。 –

答えて

2

私は、特定の型の2つの配列を両方の型の項目を持つ配列にマージする方法を示すサンプルを作成しました。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; 
    } 
} 
関連する問題