Ответ 1
Как и в случае с TypeScript 1.6, свойства в объектных литералах, которые не имеют соответствующего свойства в типе, которому они назначены, помечены как ошибки.
Обычно эта ошибка означает, что у вас есть ошибка (как правило, опечатка) в вашем коде или в файле определения. Правильным решением в этом случае было бы исправление опечатки. В вопросе свойство callbackOnLoactionHash
неверно и должно было быть callbackOnLocationHash
(обратите внимание на неправильное написание "Местоположение" ).
Это изменение также потребовало некоторых обновлений в файлах определений, поэтому вы должны получить последнюю версию .d.ts для любых библиотек, которые вы используете.
Пример:
interface TextOptions {
alignment?: string;
color?: string;
padding?: number;
}
function drawText(opts: TextOptions) { ... }
drawText({ align: 'center' }); // Error, no property 'align' in 'TextOptions'
Но я хотел сделать это
Есть несколько случаев, когда вы, возможно, намеревались иметь дополнительные свойства в своем объекте. В зависимости от того, что вы делаете, есть несколько подходящих исправлений.
Проверка только некоторых свойств
Иногда вы хотите убедиться, что несколько вещей присутствуют и правильного типа, но намерены иметь дополнительные свойства по любой причине. Утверждения типа (<T>v
или v as T
) не проверяют дополнительные свойства, поэтому вы можете использовать их вместо аннотации типа:
interface Options {
x?: string;
y?: number;
}
// Error, no property 'z' in 'Options'
let q1: Options = { x: 'foo', y: 32, z: 100 };
// OK
let q2 = <Options>{ x: 'foo', y: 32, z: 100 };
// Still an error (good):
let q3 = <Options>{ x: 100, y: 32, z: 100 };
Эти свойства и, возможно, больше
Некоторые API-интерфейсы берут объект и динамически перебирают его ключи, но имеют специальные клавиши, которые должны быть определенного типа. Добавление индекса индекса в тип отключит дополнительную проверку свойств
До
interface Model {
name: string;
}
function createModel(x: Model) { ... }
// Error
createModel({name: 'hello', length: 100});
После
interface Model {
name: string;
[others: string]: any;
}
function createModel(x: Model) { ... }
// OK
createModel({name: 'hello', length: 100});
Это собака или кошка или лошадь, еще не уверен
interface Animal { move; }
interface Dog extends Animal { woof; }
interface Cat extends Animal { meow; }
interface Horse extends Animal { neigh; }
let x: Animal;
if(...) {
x = { move: 'doggy paddle', woof: 'bark' };
} else if(...) {
x = { move: 'catwalk', meow: 'mrar' };
} else {
x = { move: 'gallop', neigh: 'wilbur' };
}
Здесь есть два хороших решения.
Укажите закрытый набор для x
// Removes all errors
let x: Dog|Cat|Horse;
или Тип утверждать каждую вещь
// For each initialization
x = <Dog>{ move: 'doggy paddle', woof: 'bark' };
Этот тип иногда открыт, а иногда не
Чистое решение проблемы "модели данных" с использованием типов пересечений:
interface DataModelOptions {
name?: string;
id?: number;
}
interface UserProperties {
[key: string]: any;
}
function createDataModel(model: DataModelOptions & UserProperties) {
/* ... */
}
// findDataModel can only look up by name or id
function findDataModel(model: DataModelOptions) {
/* ... */
}
// OK
createDataModel({name: 'my model', favoriteAnimal: 'cat' });
// Error, 'ID' is not correct (should be 'id')
findDataModel({ ID: 32 });
См. также https://github.com/Microsoft/TypeScript/issues/3755