robC robC - 2 months ago 14
TypeScript Question

TypeScript allows a property to be set but not accessed (index signature)

This interface is an example from the TypeScript docs.

The compiler shows an error for

height
, even though it allows me to set it?

// Interface taken from https://www.typescriptlang.org/docs/handbook/interfaces.html
interface SquareConfig {
color?: string;
width?: number;
[propName: string]: any;
}

const sq = <SquareConfig>{
color: 'red',
width: 7890,
height: 888
}

console.log(sq.height); // Property 'height' does not exist on type 'SquareConfig'

Answer

The syntax of indexable types is used to define a type for the properties of an object used as a map. For example:

interface Colors {
  [propName: string]: string
}
let colors: Colors = /* here, we provide the map */;
colors['blue'].indexOf('#'); // OK, "indexOf" can be used because the type is string

It is a way to define the type of properties that are dynamically named with the syntax obj['propertyName']. It's not a way to define any static properties, even if JavaScript would allow it:

colors.blue // TS Error: Property 'blue' does not exist on type 'Colors'

Therefore, the following indexable type, with any instead of a true type, is useless:

[propName: string]: any;

The specification

From the specification:

3.9.4 Index Signatures

An index signature defines a type constraint for properties in the containing type.

IndexSignature:   [ BindingIdentifier : string ] TypeAnnotation    [ BindingIdentifier : number ] TypeAnnotation

[...]

Index signatures affect the determination of the type that results from applying a bracket notation property access to an instance of the containing type, as described in section 4.13.

Comments