wiki/content/20201008092225-index_signatures.md

114 lines
2.3 KiB
Markdown
Raw Normal View History

2024-05-06 20:40:05 +00:00
---
2024-10-29 18:27:12 +00:00
date: 2020-10-08
2024-05-06 20:40:05 +00:00
id: a4bfc39c-bfe0-48f0-b58d-6dc473aa8993
title: TypeScript Index Signatures
---
# Introduction
An [object](20200826201605-objects) in
[JavaScript](20200613170905-javascript) can be accessed with a string to
hold a reference to any other JavaScript object.
``` typescript
let foo: any = {};
foo['Hello'] = 'World';
console.log(foo['Hello']); // World
```
``` typescript
class Foo {
constructor(public message: string){};
log(){
console.log(this.message)
}
}
let foo: any = {};
foo['Hello'] = new Foo('World');
foo['Hello'].log(); // World
```
``` typescript
let obj = {
toString(){
console.log('toString called')
return 'Hello'
}
}
let foo: any = {};
foo[obj] = 'World'; // toString called
console.log(foo[obj]); // toString called, World
console.log(foo['Hello']); // World
```
# Syntax
## Declaring an index signature
``` typescript
let foo:{ [index:string] : {message: string} } = {};
/**
* Must store stuff that conforms to the structure
*/
/** Ok */
foo['a'] = { message: 'some message' };
/** Error: must contain a `message` of type string. You have a typo in `message` */
foo['a'] = { messages: 'some message' };
/**
* Stuff that is read is also type checked
*/
/** Ok */
foo['a'].message;
/** Error: messages does not exist. You have a typo in `message` */
foo['a'].messages;
```
## Interfaces
As soon as you have a string index signature, all explicit members must
also conform to that index signature. A few
[Interface](20200929162220-interfaces) examples:
``` typescript
interface Foo {
x: number;
}
let foo: Foo = {x:1,y:2};
// Directly
foo['x']; // number
// Indirectly
let x = 'x'
foo[x]; // number
```
## String literals
[String Literals](20201002103357-typescript_literal_types) can also be
used in the declaration:
``` typescript
type Index = 'a' | 'b' | 'c'
type FromIndex = { [k in Index]?: number }
const good: FromIndex = {b:1, c:2}
// Error:
// Type '{ b: number; c: number; d: number; }' is not assignable to type 'FromIndex'.
// Object literal may only specify known properties, and 'd' does not exist in type 'FromIndex'.
const bad: FromIndex = {b:1, c:2, d:3};
```
## Generics
[Generics](20200929163051-typescript_generics) can also be used:
``` typescript
type FromSomeIndex<K extends string> = { [key in K]: number }
```