🦀
TypeScriptで通ってほしいのに通らないやつ
書き足していく予定。他にもあったらコメントください。
高階関数の引数を埋めてくれる関数を作りたい
const f = <T extends Record<string, unknown>>(handler: (object: T & { x: string }) => void): ((object: T) => void) => {
const x = "x";
return (object) => {
handler({ ...object, x });
};
};
const handler = (object: { x: string; y: string }) => console.info(object);
f<{ y: string }>(handler)({ y: "y" }); // 通る
f(handler)({ y: "y" }); // 通らない
型引数を与えれば通るけど、いい感じに型推論してほしい。
objectのunionをtupleのunionに変換したい
if
や switch
を使えば書けるけど、それは嫌だ。
const objToTuple = (
obj: { kind: "A"; props: { a: string } } | { kind: "B"; props: { b: string } },
): ["A", { a: string }] | ["B", { b: string }] => [obj.kind, obj.props];
関数と変数のセットを呼び出したい
これも if
とか条件分岐使えばできるけど。
type Case = { f: (x: string) => void; x: string } | { f: (x: number) => void; x: number };
const f = (c: Case) => {
c.f(c.x);
};
関数の引数によって戻り値の型を変えたい
以下の例では、引数の型がundefinedを含む場合のみundefinedを含む型で返そうとしている。
関数定義自体はうまく行くが、関数の中身がエラーになってしまう。
export const f = <S extends undefined | string>(s: S): S extends undefined ? undefined | string : string =>
s == undefined ? undefined : `hoge ${s}`;
ユニオンでなんか上手くいかない
type T = { id: string; value: { n: 0 } } | { id: string; value: { n: 1 } };
export const f = (x: T) => console.log(x);
export const g = (value: { n: 0 } | { n: 1 }) => {
if (value.n === 0) {
f({ id: "a", value });
} else {
f({ id: "a", value });
}
f({ id: "a", value }); // これだけ通らない
};
Discussion