В конце концов, это одно и то же, но первое предпочтительнее, когда это возможно.
В этом случае:
var drummer: Musician = {
instrument: "drum",
age: 28
}
вы заявляете, что drummer
является Musician
, используя аннотацию типа и присваиваете ей литерал объекта. Компилятор рад этому, потому что он может проверить, что да, назначаемый вами литерал объекта совместим с интерфейсом Musician
. Он имеет строковое свойство instrument
и числовое свойство age
.
А что если мы попробуем это:
var drummer: Musician = {};
// ~~~~~~~ <-- error!
// Type '{}' is not assignable to type 'Musician'.
// Property 'instrument' is missing in type '{}'.
drummer.instrument = "drum"
drummer.age = 28
Присваивание литерала пустого объекта значению, объявленному как Musician
, вызывает ошибку компилятора. В конце концов, пустой литерал объекта не имеет строкового свойства instrument
или числового свойства age
. И вас предупреждают об этом. Теперь, вы знаете, что следующие две строки решат эту проблему, а компилятор - нет.
Таким образом, вы можете изменить его, чтобы использовать утверждение типа вместо аннотации типа:
var drummer = <Musician>{}; // okay
drummer.instrument = "drum"
drummer.age = 28
Утверждение - это то, где вы говорите компилятору "этот объект действительно Musician
, хотя сейчас он не похож на него". Вы берете на себя ответственность за обеспечение того, что drummer
является Musician
, и освобождаете компилятор от ответственности за проверку этого для вас.
И поскольку следующие две строки добавляют необходимые свойства, все в порядке.
Первый вариант предпочтительнее, потому что вы обычно хотите, чтобы компилятор проверял ваши типы, если это возможно. Типовое утверждение отказывается от некоторой безопасности, которая хороша, пока это не так, как вождение автомобиля без ремня безопасности:
var drummer = <Musician>{}; // okay
drummer.age = 28;
// whoops, forgot the instrument, but TypeScript isn't complaining
// ... later ...
console.log(drummer.instrument.toUpperCase());
// no error at compile time
// but blows up at runtime
Бывают случаи, когда вам приходится использовать утверждения типа. Например, когда у вас есть какая-то круговая ссылка, где вам нужно построить объект по частям:
interface MarriedPerson extends Person {
spouse: MarriedPerson
}
var adam: MarriedPerson = {
age: 0,
// spouse: eve <-- can't do this before eve is defined
} as MarriedPerson;
var eve: MarriedPerson = {
age: 0,
spouse: adam
}
adam.spouse = eve; // okay now
В приведенном выше примере каждый MarriedPerson
нуждается в ссылке на MarriedPerson
... но его не будет, пока вы его не создадите. Таким образом, вы вынуждены прибегнуть к короткому промежутку времени, когда один из MarriedPerson
объектов не имеет требуемого spouse
. И поэтому требуются утверждения.
Это имеет смысл? Надеюсь, поможет; удачи!