1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

interface からunion をつくる ~ not keyof interface ~

Last updated at Posted at 2020-06-25

TL;DL

interface IHoge {
    A: string,
    B: number,
    C: boolean
}
const Hoge: IHoge = {
    A: "",
    B: 0,
    C: true
}
const h = (p: keyof IHoge) => {
    return p in Hoge ? Hoge[p] : undefined;
}
type IHogeValues = NonNullable<ReturnType<typeof h>>;
// IHogeValues = string | number | boolean

追記 2020/06/25
コメントで教えていただきました。@nagtkk さん、ありがとうございます😭

インターフェースから

interface IHoge {
    A: "a",
    B: "b",
    C: "c"
}
type IHogeValues = IHoge[keyof IHoge];

オブジェクトから

const Hoge = <const>{
  A: "a",
  B: "b",
  C: "c"
};
type IHogeValues = (typeof Hoge)[keyof typeof Hoge];

なぜつくるのか

こんなことをしたかった

const Hoge = {
  A: "a",
  B: "b",
  C: "c"
}
function Say(t: "a" | "b" | "c") {
  console.log(t);
}

Say(Hoge.A); // -> a
Say("b");    // -> b
Say("d");    // error

ライブラリが提供する列挙型だけ受け付ける関数をつくりたかった

しかし

このやり方の場合確かに問題なく動作するが、列挙型の中身が増減するたびに該当箇所を書き換える必要が出てくる → 追記漏れが怖い😭

interface から union をつくる

完成コード

interface IHoge {
    A: "a",
    B: "b",
    C: "c"
}
const Hoge: IHoge = {
    A: "a",
    B: "b",
    C: "c"
}
const h = (p: keyof IHoge) => {
    return p in Hoge ? Hoge[p] : undefined;
}
type IHogeValues = NonNullable<ReturnType<typeof h>>;
// IHogeValues = "a" | "b" | "c"

function Say(t: IHogeValues) {
    console.log(t);
}

Say(Hoge.A); // -> a
Say("b");    // -> b
Say("d");    // error

解説

ReturnType

ReturnType は与えた関数の情報を元に、その関数が返す値の型情報を取得します。
そのため、上記コード内に出てきた関数hでは、IHoge内のキー名を受け取る引数pをインデックスとしHogeから対応する値を返し、存在しない場合はundefinedを返します。
❗️p は動的に決まるため仕様上return Hoge[p]とは書けません。(keyof IHogeしているのに。。。)

そのため関数hが返す値は"a" | "b" | "c" | undefinedになります。

NonNullable

NonNullableは受け取ったTypeからundefinednullを除いた値を返します。

そのためReturnTypeから受け取った"a" | "b" | "c" | undefined"a" | "b" | "c"にすることが出来ます。

あとがき

これで追記漏れなどもなくなるので安心ですね!

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?