Open15

type-challengesをやっていく

Hirotaka MiyagiHirotaka Miyagi

Pick

  • 最初からわからん
  • Kで与えられるunion型に対してMapped Typeにすれば良いことはわかったけど、Tのindexとするにはどうすればいいんだ…というところで詰まった
  • なるほどkeyof...
Hirotaka MiyagiHirotaka Miyagi

Tuple to Object

  • Tは何かしらの配列
  • 配列をunion型にできれば良い?
  • typeof T[number] じゃだめなんか?
  • 'T' only refers to a type, but is being used as a value here. これなんだっけ
    • あーTは型であり値ではないのか
  • うーんタイムアップ

解説を読む

  • https://zenn.dev/link/comments/d134e180bd721f
  • なるほどー、Indexed Access Typesをちゃんと理解できてなかった感がある
  • オブジェクトの場合はkeyをインデックスとして渡すが、配列の場合は number を渡すのか
    • 複数の型が含まれる配列の場合はどうなるんだ
    • type T = (string | number | boolean)[][number]
      • Tは string | number | boolean になった、言われてみれば納得
Hirotaka MiyagiHirotaka Miyagi

First of Array

  • 配列の最初の型を得る
  • T[0] で大体のテストケースは通ったけど、 First<[]> でneverが来て欲しいがundefinedになってる
  • conditional typeか?
  • T[0] extends undefined ? never : T[0] これだと undefined を期待するパターンでneverになる
  • テストケースよく考えられてるな
  • type First<T extends any[]> = T[number] extends never ? never : T[0] これでいけた

他の回答を読む

Hirotaka MiyagiHirotaka Miyagi

Length of Tuple

  • 要素の数を数える?型で?
  • 何もわからない

解説を読む

Hirotaka MiyagiHirotaka Miyagi

Exclude

  • TもUもunion type
  • union type同士の差を得ることってできるんか?
  • わからん

解説を読む

Conditional Types の条件部において T extends U の T が ユニオン型である場合 T に対して反復処理を行い各要素に条件を適用します。

  • conditional typesを使うとなると、Tはunion typeなので、各要素を反復して処理される
    • MyExclude<'a' | 'b' | 'c', 'a'> の場合、 ('a' | 'b' | 'c') と 'a' を比較するのではなくて、各要素が 'a' と比較されるってことか
  • うーんこれは知識がないと解けなかったかもなあ
  • 知らなかったし、今まで何やってるのかわからなかったライブラリの型とかも読めるようになりそう
Hirotaka MiyagiHirotaka Miyagi

Awaited

  • Promiseを外したい
  • TがPromiseを継承してたらゴニョゴニョ
  • infer案件では?
  • type MyAwaited<T> = T extends Promise<infer U> ? U : never これで行けそうな気がしたけど、ネストされたPromiseでエラーになってる…
  • Promiseのネストを外したい
  • Promiseのネストをするな
  • わからない

回答を読む

Hirotaka MiyagiHirotaka Miyagi

If

  • conditional typeでCがtrueだったらT, CがfalseだったらFを返せばいいんでは?
  • type If<C, T, F> = C extends true ? T : F これでええやんと思ったけど、Cでnullが渡されるケースでエラーになってくれていないな
  • type If<C extends boolean, T, F> = C extends true ? T : F boolean指定すれば良いか
Hirotaka MiyagiHirotaka Miyagi

Includes

  • Excludesの逆で考えれば良いかな
  • TはArrayなので、union typeに変換できればU extends Tができる?
    • type ToUnion<T extends any[]> = T[number] でunion typeは作れる
  • type Includes<T extends readonly any[], U> = U extends T[number] ? true : false これである程度のパターンは通るけど、 Expect<Equal<Includes<[{}], { a: 'A' }>, false>> とかが通ってないな
    • trueが返ってきてる
  • グエーわからん

回答を見る

  • https://zenn.dev/link/comments/907e84d626d383
    • うーん…?
  • https://zenn.dev/syun43/articles/9d8bc41ddae9be#includes
    • あーなるほど…
  • 以下の処理を組み合わせる
    • 型の比較 ... Equal<A, B> でbooleanを返す
    • Varadic Tuple Typeで配列の中身を先頭(First)とその他(Rest)に分割する
    • FirstとUを比較し、trueなら終了、falseならRestを使って再帰処理
  • Equalは type-challenges/utils の型を使ってる回答が多い感じかな?
    • https://github.com/type-challenges/type-challenges/blob/main/utils/index.d.ts#L7-L9
    • type MyEqual<X, Y> = X extends Y ? Y extends X ? true : false : false こんな感じでXとYが互いに代入可能なのであればEqualと見なせるんじゃ?
      • と思ったけど Expect<Equal<Includes<[{ a: 'A' }], { readonly a: 'A' }>, false>> で失敗してる
      • type test = MyEqual<{ a: 'A' }, { readonly a: 'A' }> なんでやこれでtrueが返ってくる

これ両方trueが返ってくるんだけどそういうもんなのか?

type test2 = { a: 'A' } extends { readonly a: 'A' } ? true : false
type test3 = { readonly a: 'A'} extends { a: 'A' } ? true : false