Closed10

TypeScriptで型関数を書く練習をする

りんすりんす

Conditional types に一般型を入れて、その型にユニオン型を入れると、Conditional typesは分配的な挙動をする。
この挙動を防ぐには、extendsの両側を[]で囲む。

type A<T> = T extends any ? T[] : never;
// A<string | number> => string[] | number[]

type B<T> = [T] extends [any] ? T[] : never;
// B<string | number> => (string | number)[]

https://www.typescriptlang.org/play?#code/C4TwDgpgBAggPAFQHxQLxQVCAPYEB2AJgM5QCG+IUA-BgNoC6UAXFPhAG4QBOA3AFAB6QbDjFg3AJb4A5lAA+bAK4BbAEY8UqFOKmzGC5ep6N+QkQnDQA5AApd0uYvyqN3AJSNrUSaXwB7YHJiYkkZfDI1ABtoYH8oUEgoawd9JmdXEwZrADp+AGN-fHFyVnhUpyM3LSg6ACIACQgoqP86gBooAEYAJgBmBgEzROgAIUQaugQmHDwiUjoKECZaBANWdi4+cyhxisMXY24tFHsJRwPMj1MCopK1Vj3z2Uujycbm1o7u-sH+IA

りんすりんす

なんかの役に立たないかと思ってC++のenable_ifっぽいものを書いたけど、TypeScriptではうまく生かせない
C++では条件に当てはまらずにテンプレートのSubstitutionに失敗した時に次の候補を見ることでコンパイルエラーを回避できるというのがSFINAEだったけど、TypeScriptではnever型がそもそも合法な型だし、コンセプトから崩れてる

どうにかして、うまく関数の型パラメータ部分に条件を書けないものか

// B に渡された型が true であれば T が有効化され、そうでなければ Err が選択される型
type EnableIf<B, T = void, Err = never> = B extends true ? T : Err;

https://www.typescriptlang.org/play?#code/PTAECFUawZEI7RVBkDEMh9BkNHqgZBlAFwE4FcCmog5gyBCDAoA4MoAKqGoJDmgnUqBoyooIAMgugyBiDEYFYMgigwVQAUWzZagDwTAeUaJA0QwoAUJgCeAB0JCAdgEMARgBt8ASQBmAHnAAaaqAC8oAG4B7AJYATKyLF2N+e-mwAfLYQoPgAHpj4Gq4Azlh4hAD81gBcwqIA3PKKqoSGMQDKOM4aAOamVEF2NOGR0XExxWWgyTgEoGnGWnox+FnyxrgaAMaYzo4aoGZUVgCqoRFRscLa+kZm+UXYJeWVAQEAFJhpM6AA+mmzAJSgAN7yoI+gwxMxjgYAdHqOpQcARDQABZaOJaUCNbbNZRqD5-K5ZAC+2WM-0B+D03z+ViGrnwxhK+Fc8PkIFAAEFsKVcABbKKYUCOYxYXKgADkOLxBNcrNAzjiGkc9JBMWcpVWBiwjlAKi02C0tMiYkZzLUbJ8fmwrI+AwOAEYAEwAZmx0U5PiJWSAA

りんすりんす
// T <: U は, T が U のサブタイプであるという意味

// never型は ⊥型; ∀t, never <: t
type OrNever<T> = T | never;    // T | never == T
type AndNever<T> = T & never;   // never

// unknown は ⊤型; ∀t, t <: unknown
type OrUnknown<T> = T | unknown;    // => unknown
type AndUnknown<T> = T & unknown;   // => T
このスクラップは2024/03/30にクローズされました