首页 > 解决方案 > 为什么 typescript 不能识别此语句中的联合类型?

问题描述

我有以下代码:

type testUnion = Array<any> | string;

class testClass {
testProp: testUnion;
}

const bar = new testClass()
bar.testProp.forEach(...) //property forEach does not exist on type testUnion

但是 testUnion 是一个数组或一个字符串,并且每个属性都存在于 Array 类中。为什么打字稿不将其视为数组或字符串。我得到的唯一智能是一个方法'valueOf'

有任何想法吗?

编辑
下面的完整代码,Developer 类中的 loadTrait 方法是有问题的,我还包括了 Trait 类和所有相关接口,以防有任何其他建议。

interface devInit {
    locations: Array<Location>;
    traits: Array<Trait>;
    props: developerProp;
    name: string;
}

interface developerProp {
    acceptedMaritalStatuses: maritalStatusType;
    ageTop: number;
    ageBottom: number;
    income: number;
    majorCCRequired: boolean;
}
class Developer {
    locations: traitLocationType;
    props: developerProp;
    name: string;
    private traits: Array<Trait> = [];
    constructor(init: devInit) {
        Object.assign(this, init);
        $notesApi.subscribe((_notes) => {
            this.notesApi = _notes;
        });
    }
    private notesApi: notesApiType;
    //only load after traits have been loaded.
    private loadExternalNotes() {
        //@ts-ignore
        if (_notes === '') return;
        this.locations.forEach((_location) => {
            const gifts = new Note(
                'gifts',
                this.notesApi[this.name][_location.name].gifts
            );
            const notes = new Note(
                'gifts',
                this.notesApi[this.name][_location.name].notes
            );
            _location.addNote(gifts);
            _location.addNote(notes);
        });
    }
    private loadTraits() {
        this.traits.forEach((_trait) => {
            _trait.runRules();
            if (!_trait.key) return;
            if (_trait.key === 'locations') {
                if(Array.isArray(_trait.value))
                _trait.value.forEach((_traitValue) => {
                    this.locations.push(_traitValue);
                });
            }
        });
    }
}

class Trait {
    constructor(traitKey: traitKeyType, traitValue: traitValueType) {
        this._key = traitKey;
        this._value = traitValue;
    }
    private _key: traitKeyType;
    private _value: Array<any> | string;
    private status = false;
    private notes: Array<Note> = [];
    private rules: Array<Rule> = [];
    get key() {
        if (!this.status) return null;
        return this._key;
    }
    get value() {
        if (!this.status) return null;
        return this._value;
    }
    addRule(rule: Rule) {
        this.rules.push(rule);
        return this;
    }
    runRules() {
        const getInfoFromRules = (_rule: Rule) => {
            _rule.run();
            this.notes.push(_rule.note);
            return _rule.status;
        };
        this.status = this.rules.map(getInfoFromRules).indexOf(false) === -1;
    }
}
type traitValueType = Array<any> | string;
// | maritalStatusType
// | traitLocationType
// | traitLocationType
// | boolean;

type maritalStatusType = 'married' | 'coHab' | 'singleMale' | 'singleFemale'[];
type traitLocationType = Array<Location>;

标签: typescript

解决方案


因为它可以是数组或字符串。TS不知道是哪个,你要告诉它...

您可以使用类型检查:

if (Array.isArray(bar.testProp)) {
  bar.testProp.forEach(...)  // this is fine 
}

或者如果你知道它实际上是一个数组,你可以使用类型断言:

(bar.testProp as Array<any>).forEach(...) // also fine

推荐阅读