1
0

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 1 year has passed since last update.

【Typescript】一部のプロパティの型を上書きする関数

Last updated at Posted at 2022-04-30

はじめに

ある日、こんなことが起こった。
サーバーサイドから送られてくるオブジェクトの一部のプロパティがstringの時とnumberの時があるやん。。

const user = {
  id: 1,
  name: 'james',
  age: 20,
}

const user = {
  id: 1,
  name: 'mike',
  age: '20'
}

例ではageプロパティがnumberの時とstringの時があり、「これどちらかに揃えてくれよ〜〜」と思ったがサーバーサイドの方曰く、何かしらの理由でしょうがないらしい。。
普段typescriptで開発しているし、ageがstringの時とnumberの時でそれぞれ型を定義するのは良くないから、どうしようと思った時の対処法を考えてみた。

案① それぞれ型を作成する

これは普通に良くない。

type User = {
  id: number;
  name: string;
  age: number;
}

type User2 = {
  id: number;
  name: string;
  age: string;
}

案② Omitを使う

  • 冗長
  • age: stringの部分は実質なんでも追加できるため、ageをタイポしてもわからない
  • 他にも上書きしたい時が出てきたらまた作成しないといけない。
type User = {
  id: number;
  name: string;
  age: number;
}

type OmitUser = Omit<User, 'age'> & {
  ag: string // タイポしてもわからない
}

const user: OmitUser = {
  id: 1,
  name: 'mike',
  age: '20' // ここで初めてタイポしてることに気づく
}

結論

ジェネリックス + Omitで型関数を作成してみた。
ぱっと見てわかりやすい!!

type Overwrite<T, U extends { [Key in keyof T]?: unknown }> = Omit<
  T,
  keyof U
> & U;

const user2:Overwrite<User, {age: string}> = {
  id: 1,
  name: 'mike',
  age: '20'
}

const user3:Overwrite<User, {age: string[]}> = {
  id: 1,
  name: 'mike',
  age: ['20', '21'] // ageが配列になることはありえないけど、例として作成してます。
}

解説

上書きする関数をジェネリックスOmitで定義しています。
ここではTUser型が入り、Uには変換したいプロパティと変換したい型を定義しています。
extendsを使用し、keyof T つまりUser型(T)のキーのみを受け入れるように制限しています。
そして、Omitで指定したT(User型のキー)からkeyof U(ageプロパティ)を削除し、新たに
U(age: string)を追加しているといった感じですね。
これで一部のプロパティの型を上書きする関数を作成できました。

type Overwrite<T, U extends { [Key in keyof T]?: unknown }> = Omit<
  T,
  keyof U
> & U;

Overwrite<User, {age: string}> // タイポするとエラー出ます。

おわりに

共通の処理をジェネリックス等を使用してまとめた関数を作成するとtypescript見習いから
初心者になれた気がします。

1
0
0

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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?