mirror of
https://github.com/alrayyes/wiki.git
synced 2024-12-01 15:26:23 +00:00
113 lines
2.3 KiB
Markdown
113 lines
2.3 KiB
Markdown
|
---
|
|||
|
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 }
|
|||
|
```
|