LoginSignup
79
38

More than 1 year has passed since last update.

TypeScriptの組み込み型関数 Recordの使いどころ

Last updated at Posted at 2019-11-16

Recordの使いどころ

Recordについて調べたので書く

最小サンプル

//Record<K,T>
type SmallRecord = Record< "a"|"b"|"c" , string >

SmallRecord は以下の型として展開される

// SmallRecord
{
a : string,
b : string,
c : string
}

つまり Kに列挙された型がプロパティになり、それぞれTを持つオブジェクト型になる。

サンプルコード

以下のようなオブジェクトがある。

 const users = {
    "suzuki" : {
        age : 26,
        name : "suzuki"
    },
    "sato" : {
        name : "sato",
        age : 32
    },
    "takahashi" : {
        name : "takahashi",
        age : 40,
    },
    "tanaka" : {
        name : "tanaka",
        age : 25,
    }
}

上のオブジェトを下記の形へ変形させる 関数を考える

{
    "suzuki" :26,
    "sato" : 32,
    "takahashi" : 40,
    "tanaka" :25
)

素直に書くとこんな感じでしょうか?

const usersAgeFn1 = (users:{[key:string] : {age:number}}) => {
    let ages : {[key:string]:number} = {}
    for( let [key,value] of Object.entries(users) ){
        ages[key] = value.age
    }
    return ages
}

const usersAge1 = usersAgeFn1(users)

別に上でも悪くないが、戻り値の型は {[key:string]:number}になり、プロパティが維持できない。(コード補完が効かない)

RecordとGenericsを併用して書く

※ asが多いが許して

const usersAgeFn2 = <T extends {[key:string]:{age:number}}>(users:T) => {
    let ages = {} as Record<keyof T , number>
    for( let [key,value] of Object.entries(users) ){
        ages[key as keyof T] = value.age
    }
    return ages
}
const usersAge2 = usersAgeFn2(users)

これで戻り値の型はプロパティを維持した状態になる(コードの補完が効く)

Mapped Types でも同じ事はできる。

サンプルのコードだとこっちの方がシンプルに見えるかもしれない。

const usersAgeFn3 = <T extends {[key:string]:{age:number}}>(users:T) => {
    let ages = {} as {[P in keyof T]:number}
    for( let [key,value] of Object.entries(users) ){
        ages[key as keyof T] = value.age
    }
    return ages
}

const usersAge3 = usersAgeFn3(users)
79
38
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
79
38