использование интерфейса для ввода анонимного объекта в typescript


У меня есть интерфейс IBase и переменная, которая содержит несколько других объектов (в примере я только что добавил base для лучшей демонстрации)

interface IBase {
    height?:number;
    width?:number;
}

var element = {
    base: {

    }
}

Как я могу сказать, что объект, что изменяемый элемент.база имеет это от типа IBase? Я знаю, что я мог бы создать тип для переменной элемента, который содержит типы базы и т. д., Но это также возможность ввести этот сценарий, не делая этого.

4 5

4 ответа:

Ответ Ван ден Бринк-это хорошо. Так же, как демо другой вариант:

var element = {
    base: <IBase> {

    }
}

Это также даст желаемый intellisense:

Введите описание изображения здесь

Вы случайно вызвали проблему с объявлением интерфейса. Это тонкая вещь, с которой вы столкнетесь со структурно типизированными языками.

interface IBase {
    height?:number;
    width?:number;
}
Поскольку все свойства являются необязательными, интерфейс по существу является {}. то есть любой объект удовлетворяет этому интерфейсу. Это слишком общее понятие, чтобы быть полезным в большинстве случаев.

Например, вполне допустимо сделать следующее:

var x: IBase = {
    a: 'efsdsdf',
    v: 'sdfdsf' 
};

Я думаю, вы согласитесь, что на самом деле этот объект не полезно нигде, где я хотел бы использовать объект IBase.

С этим вы можете найти самое изящное решение-создать интерфейс, который соответствует вашему определению element.

interface IElement {
    base: {
        height?:number;
        width?:number;
    }
}

var element: IElement = {
    base: {
        height: 4
    }
}

Если вы измените объявление элемента var на следующее, Он знает, что такое база:

var element: { base: IBase; } = {
    base: {
    }
}

Примечание: Вы также можете создать новый интерфейс для него, как это, что делает его немного более многоразовым: интерфейс IElement { основание: IBase; } а затем использовать его, как здесь: var element: IElement = { base: {} }

Отличный ответ от @basarat теперь нуждается в небольшом обновлении; использование угловых скобок теперь приводит к ошибке tslint:

[tslint] утверждение типа с использованием синтаксиса ' ' запрещено. Вместо этого используйте синтаксис "as". (no-angle-bracket-type-assertion)

Решение простое:

const element = {
    base: {} as IBase
}

Это также обеспечивает intellisense (автозаполнение), которое вы также хотите.