What's the Change?
Old Behavior
Prior to 1.6, TypeScript didn't do a good job detecting problems in object literals, especially when the property you tried to specify was optional:
interfaceTextOptions{alignment?: string;color?: string;padding?: number;}functiondrawText(opts: TextOptions){ ... }// None of these were errors beforedrawText({align: 'center'});// OopsdrawText({colour: 'grey'});// OopsdrawText({pading: 32});// OopsNew Behavior
As of 1.6, properties in object literals that do not have a corresponding property in the type they're being assigned to are flagged as errors:
drawText({align: 'center'});// Error, no property 'align' in 'TextOptions'But I meant to do that
There are a few cases where you may have intended to have extra properties in your object. Depending on what you're doing, there are several appropriate fixes
Type-checking only some properties
Sometimes you want to make sure a few things are present and of the correct type, but intend to have extra properties for whatever reason. Type assertions (<T>v or v as T) do not check for extra properties, so you can use them in place of a type annotation:
interfaceOptions{x?: string;y?: number;}// Error, no property 'z' in 'Options'letq1: Options={x: 'foo',y: 32,z: 100};// OKletq2=<Options>{x: 'foo',y: 32,z: 100};// Still an error (good):letq3=<Options>{x: 100,y: 32,z: 100};These properties and maybe more
Some APIs take an object and dynamically iterate over its keys, but have 'special' keys that need to be of a certain type. Adding a string indexer to the type will disable extra property checking
Before
interfaceModel{name: string;}functioncreateModel(x: Model){ ... }// ErrorcreateModel({name: 'hello',length: 100});After
interfaceModel{name: string;[others: string]: any;}functioncreateModel(x: Model){ ... }// OKcreateModel({name: 'hello',length: 100});This is a dog or a cat or a horse, not sure yet
interfaceAnimal{move;}interfaceDogextendsAnimal{woof;}interfaceCatextendsAnimal{meow;}interfaceHorseextendsAnimal{neigh;}letx: Animal;if(...){
x ={move: 'doggy paddle',woof: 'bark'};}elseif(...){
x ={move: 'catwalk',meow: 'mrar'};}else{
x ={move: 'gallop',neigh: 'wilbur'};}Two good solutions come to mind here
Specify a closed set for x
// Removes all errorsletx: Dog|Cat|Horse;
or Type assert each thing
// For each initializationx=<Dog>{move: 'doggy paddle',woof: 'bark'};This type is sometimes open and sometimes not
A clean solution to the "data model" problem using intersection types:
interfaceDataModelOptions{name?: string;id?: number;}interfaceUserProperties{[key: string]: any;}functioncreateDataModel(model: DataModelOptions&UserProperties){/* ... */}// findDataModel can only look up by name or idfunctionfindDataModel(model: DataModelOptions){/* ... */}// OKcreateDataModel({name: 'my model',favoriteAnimal: 'cat'});// Error, 'ID' is not correct (should be 'id')findDataModel({ID: 32});
What's the Change?
Old Behavior
Prior to 1.6, TypeScript didn't do a good job detecting problems in object literals, especially when the property you tried to specify was optional:
New Behavior
As of 1.6, properties in object literals that do not have a corresponding property in the type they're being assigned to are flagged as errors:
But I meant to do that
There are a few cases where you may have intended to have extra properties in your object. Depending on what you're doing, there are several appropriate fixes
Type-checking only some properties
Sometimes you want to make sure a few things are present and of the correct type, but intend to have extra properties for whatever reason. Type assertions (
<T>vorv as T) do not check for extra properties, so you can use them in place of a type annotation:These properties and maybe more
Some APIs take an object and dynamically iterate over its keys, but have 'special' keys that need to be of a certain type. Adding a string indexer to the type will disable extra property checking
Before
After
This is a dog or a cat or a horse, not sure yet
Two good solutions come to mind here
Specify a closed set for
xor Type assert each thing
This type is sometimes open and sometimes not
A clean solution to the "data model" problem using intersection types: