かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

TypeScript Object を Object.keys() を使ったループの型エラーにハマる

TypeScript で Object.keys(obj) でキーの配列を作ってループさせてループ内でキーでオブジェクトのデータにアクセスしようとして型エラーになってしまったのメモ

e.g.

例としてデータ構造が良くないけど、ID をキーにしたオブジェクトみたいなイメージで

const idols = {
  hosimiya: {name: '星宮いちご', type: 'cute', brand: 'Angely Sugar'},
  kirija: {name: '霧矢あおい', type: 'cool', brand: 'FUTURING GIRL'},
  shibuki: {name: '紫吹蘭', type: 'sexy', brand: 'SPICY AGEHA'},
};

Object.keys(idols).map((key) => {
  const data = idols[key];
  // => Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ hosimiya: …
  // => No index signature with a parameter of type 'string' was found on type '{ hosimiya: …
  console.log(data);
});
  • Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ hosimiya: …
  • No index signature with a parameter of type 'string' was found on type '{ hosimiya: …

オブジェクトに [key] でアクセスすると暗黙的に型変換された keyidols オブジェクトのインデックスと一致しないということっぽい。
(ᐡ •̥ ̫ •̥ ᐡ) なんもわからん…

Object.keys で作られる配列がオブジェクトのキーの配列だと証明できればOK

keyof を使うとプロパティ名を | でつないだ型 ( プロパティ名の直和型 ) が作れる

interface Soleil {
  'hosimiya': { name: string, type: string, brand: 'string' };
  'kirija': { name: string, type: string, brand: 'string' };
  'shibuki': { name: string, type: string, brand: 'string' }; 
}

type SoleilKey = keyof Soleil;
// => type SoleilKey = 'hosimiya' | 'kirija' | 'shibuki';

Object.keys(idols)SoleilKey[] になっていれば、map に渡される引数は SoleilKey である。ということになるっぽい。
修正するとこんな感じ。

interface idolData {
  name: string;
  type: string;
  brand: string;
}

interface Soleil {
  hosimiya: idolData;
  kirija: idolData;
  shibuki: idolData;
}

const idols: Soleil = {
  hosimiya: {name: '星宮いちご', type: 'cute', brand: 'Angely Sugar'},
  kirija: {name: '霧矢あおい', type: 'cool', brand: 'FUTURING GIRL'},
  shibuki: {name: '紫吹蘭', type: 'sexy', brand: 'SPICY AGEHA'},
};

(Object.keys(idols) as (keyof Soleil)[]).map((key) => {
  const data = idols[key]; // 👌👌👌
  console.log(data);
});

₍ ᐢ. ̫ .ᐢ ₎👌 できた

おまけ

今回のレベルだと [key: string] で型定義してしまえば、map の所でゴニョゴニョしなくても大丈夫っぽい

interface idolData {
  name: string;
  type: string;
  brand: string;
}

interface Idols {
  [key: string]: idolData;
}

const idols: Idols = {
  kurebayashi: {name: '紅林珠璃', type: 'sexy', brand: 'Sangria Rosa'},
  Amahane: {name: '天羽まどか', type: 'cute', brand: 'Angely Sugar'},
  Kurosawa: {name: '黒沢凛', type: 'cool', brand: 'Dance Fusion'},
};

Object.keys(idols).map((key) => {
  const data = idols[key]; // 👌👌👌
  console.log(data);
});

TypeScript チョットづつ慣れてきてるけどまだ何もわからん…


[参考]

速習 TypeScript 第2版 速習シリーズ

速習 TypeScript 第2版 速習シリーズ

React localhost でも https で動かしたい

create-react-app, react-scripts で作った React アプリを外部ライブラリやAPIの都合で localhost の時も https で動かしたい時のメモ

.env に HTTPS=true を設定すればOK

HTTPS=true のオプション付きで起動すれば localhosthttps で起動できるようです。
create-react-app, react-scripts で作成した react アプリは自動的に .env ファイルを見るようになっているので、ここに HTTPS=true を設定すればOK

# .env
HTTPS=true

この設定をして yarn start すれば自動的に https://localhost:3000 で起動する。 ヤッタネ ₍ ᐢ. ̫ .ᐢ ₎👌


[参考]

Long time no sea[ 初回盤 / ボーナスディスク付き ]

Long time no sea[ 初回盤 / ボーナスディスク付き ]

さよポニの みぃな のアルバムめちゃ良い〜

Git マージコミットを残したまま rebase したい。

別 PR で機能を取り込んだりしたマージコミットのあるブランチでマージコミットを残したまま rebase したい時のメモ

git rebase -i だとマージコミットが消えてしまう

e.g.

$ git log --graph --oneline
* f3084e4 (HEAD -> master) 時はきた!
* defc249 ねこいいよね
* 3864499 (origin/master) Merge pull request #1 from Mikan/wow
|\
| * 99fb7bd (origin/wow, wow) まちカドまぞく2期決定
|/
* 22301d8 千代田もも
* af375c9 シャミ子
$ git rebase -i af375c9

👇 merge commit が表示されない

pick 22301d8 千代田もも
pick 99fb7bd まちカドまぞく2期決定
pick defc249 ねこいいよね
pick f3084e4 時はきた!

# Rebase af375c9..f3084e4 onto f3084e4 (4 commands)

rebase が完了すると merge commit が消えた履歴になる

$ git log --graph --oneline
* 7817181 (HEAD -> master) 時はきた!
* 82e603d ねこいいよね
* ca3fc82 まちカドまぞく2期決定
* d4132d0 桃色魔法少女
* af375c9 シャミ子

マージコミットを残したい時は -p ( --preserve-merges ) オプションを使用する

$ git rebase -i -p af375c9

👇 merge commit も表示される

pick 22301d8 千代田もも
pick 99fb7bd まちカドまぞく2期決定
pick 3864499 Merge pull request #1 from Mikan/wow
pick defc249 ねこいいよね
pick f3084e4 時はきた!

# Rebase af375c9..f3084e4 onto af375c9 (5 commands)

rebase しても merge commit が維持される

$ git log --graph --oneline
* 7817181 (HEAD -> master) 時はきた!
* 82e603d ねこいいよね
*   8689d15 Merge pull request #1 from Mikan/wow
|\
| * ca3fc82 まちカドまぞく2期決定
|/
* d4132d0 桃色魔法少女
* af375c9 シャミ子

マージされたコミットのブランチ名などは失われてしまうようですが、 merge commit を維持したまま rebase することができました。歴史改竄のテクニックをまた一つ覚えてしまった。そもそも merge commit を挟んで rebase する必要が出ないように気をつけるべきだとは思いますが…


[参考]

まちカドまぞく2期嬉しい!