¿Por qué recibo un error “El literal del objeto solo puede especificar propiedades conocidas”?

Acabo de actualizar de TypeScript 1.5 a la última y veo un error en mi código:

interface Options { /* ... others ... */ callbackOnLocationHash?: boolean; } function f(opts: Options) { /* ... */ } // Error: Object literal may only specify known properties, // and 'callbackOnLoactionHash'does not exist in type 'Options'. f( { callbackOnLoactionHash: false }); 

El código me parece bien. ¿Qué pasa?

(Versión alternativa del universo: reconozco el error tipográfico, y realmente quise escribir eso. ¿Qué debo hacer para eliminar el error?)

A partir de TypeScript 1.6, las propiedades en literales de objetos que no tienen una propiedad correspondiente en el tipo al que se les asignan se marcan como errores.

Por lo general, este error significa que tiene un error (generalmente un error tipográfico) en su código o en el archivo de definición. La solución correcta en este caso sería corregir el error tipográfico. En la pregunta, la propiedad callbackOnLoactionHash es incorrecta y debería haber sido callbackOnLocationHash (tenga en cuenta la ortografía incorrecta de “Ubicación”).

Este cambio también requirió algunas actualizaciones en los archivos de definición, por lo que debe obtener la última versión de .d.ts para las bibliotecas que está utilizando.

Ejemplo:

 interface TextOptions { alignment?: string; color?: string; padding?: number; } function drawText(opts: TextOptions) { ... } drawText({ align: 'center' }); // Error, no property 'align' in 'TextOptions' 

Pero quise hacer eso

Hay algunos casos en los que puede haber pensado tener propiedades adicionales en su objeto. Dependiendo de lo que estés haciendo, hay varias correcciones apropiadas

Verificación de tipos solo de algunas propiedades

A veces querrás asegurarte de que algunas cosas estén presentes y del tipo correcto, pero pretenden tener propiedades adicionales por la razón que sea. Las aserciones de tipo ( v o v as T ) no comprueban las propiedades adicionales, por lo que puede usarlas en lugar de una anotación de tipo:

 interface Options { x?: string; y?: number; } // Error, no property 'z' in 'Options' let q1: Options = { x: 'foo', y: 32, z: 100 }; // OK let q2 = { x: 'foo', y: 32, z: 100 }; // Still an error (good): let q3 = { x: 100, y: 32, z: 100 }; 

Estas propiedades y tal vez más

Algunas API toman un objeto e iteran dinámicamente sobre sus claves, pero tienen claves “especiales” que deben ser de cierto tipo. Agregar un indexador de cadenas al tipo desactivará la comprobación de propiedades adicionales

antes de

 interface Model { name: string; } function createModel(x: Model) { ... } // Error createModel({name: 'hello', length: 100}); 

Después

 interface Model { name: string; [others: string]: any; } function createModel(x: Model) { ... } // OK createModel({name: 'hello', length: 100}); 

Este es un perro o un gato o un caballo, aún no estoy seguro

 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' }; } 

Dos buenas soluciones vienen a la mente aquí

Especifique un conjunto cerrado para x

 // Removes all errors let x: Dog|Cat|Horse; 

o Escriba afirmar cada cosa

 // For each initialization x = { move: 'doggy paddle', woof: 'bark' }; 

Este tipo a veces está abierto y otras veces no

Una solución limpia al problema del “modelo de datos” usando tipos de intersección:

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

Ver también https://github.com/Microsoft/TypeScript/issues/3755