🦀

TypeScriptで通ってほしいのに通らないやつ

2022/06/29に公開

書き足していく予定。他にもあったらコメントください。

高階関数の引数を埋めてくれる関数を作りたい

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に変換したい

ifswitch を使えば書けるけど、それは嫌だ。

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

ログインするとコメントできます