[TypeScript] Mapped Type

Index Signature

type Fruit = {
  name: string
  color: string
  mass: number
}
 
type Dict<T> = { [k: string]: T } // <- index signature
 
const fruitCatalog: Dict<Fruit> = {}
fruitCatalog.apple // Fruit

Using index signature, we will get any key, basicly:

fruitCatalog.apple // Fruit
fruitCatalog.car   // Fruit
fruitCatalog.house // Fruit

 

We want to imporve the type, so that we can limit what key we want to use:

type Fruit = {
  name: string
  color: string
  mass: number
}

type MyFruit = {[FruitKey in "apple" | "cherry"]: Fruit}

function printFruitCatalog(fruitCatalog: MyFruit) {
  fruitCatalog.cherry
  fruitCatalog.apple
  fruitCatalog.pineapple // ERROR: roperty 'pineapple' does not exist on type 'MyFruit'.
}

 

  • in keyword is the maped type.
  • Index signatures can be on all strings or all numbers, but not some subset of strings or numbers.

Notice: 

the following syntax is wrong:

type MyRecord = { [key: "apple" | "cherry"]: Fruit }  // Wrong
type MyRecord = { [key in "apple" | "cherry"]: Fruit } // Correct

 


 

Record

Now we want to make a more gemeralized type based on MyFruit:

type MyFruit = {[FruitKey in "apple" | "cherry"]: Fruit}
type MyRecord<KeyType extends string, ValueType> = {[Key in KeyType]: ValueType}

function printFruitCatalog(fruitCatalog: MyRecord<"apple" | "cherry", Fruit>) {
  fruitCatalog.cherry
  fruitCatalog.apple

  fruitCatalog.pineapple // ERROR
}

 

posted @ 2022-08-17 15:08  Zhentiw  阅读(31)  评论(0编辑  收藏  举报