タオルケット体操

サツバツいんたーねっとでゲームとかガジェットのレビューとかをします

TypeScriptで既存の関数の引数と返り値の型情報をコピーする方法

TypeScriptにはType infer in ConditionalTypeという便利機能があり、それを利用すると既存の型定義から柔軟に特定の方を取り出すことができます。
そして利用頻度が高そうなものについては組み込みの型定義がいくつか存在します。

関数の型定義から引数を取り出すのは Parameters<T> で、この型引数に関数の定義を与えることでその関数の引数がTupleとして返ってきます。
ちなみに返り値は ReturnType<T> で取り出すことが出来ます。

function testFunc(a: string, b: number, c: boolean): {a: string, b: number, c: boolean} {
  return {a, b, c};
}

type TestFuncArgs = Parameters<typeof testFunc>;
// TestFuncArgs = [a: string, b: number, c: boolean];

type TestFuncRet = ReturnType<typeof testFunc>;
// TestFuncRet = {a: string, b: number, c: boolean};
続きを読む

Taptekキーボードの無線接続方法について(マニュアルを捨ててしまったアホのための忘備録)

  • ペアリングモードへの移行

    Fn + を一秒以上長押しすると が点滅するのでお好きなデバイスでペアリング

  • ペアリングスイッチのやり方

    Fn + 1/2/3 で切り替えられる。古いステマブロガーの記事だとFn + Q/W/E ということになっているが、おそらくテストファームの仕様か、使わずに書いた適当なコピペ記事のどちらかだとおもわれる。

なんでこんなの書いたかって?説明書を捨てたからだよ!

Taptek自体の簡単なレビュー

ゲーム用としてならOK、作業用の普段使いとしてはクソ

続きを読む

Apex Legendsについて

遥か未来、太陽系は開拓宙域「フロンティア」を牛耳る巨大星間企業IMCとそれに対抗するレジスタンス組織ミリシアによる熾烈な戦争が続いていました。
僕も当時、巨大兵器タイタンを駆るエリート兵士、パイロットの一人としてPS4コントローラーで参戦して壁を走ったり異空間に逃げ込んだりしてました。

時は流れ現代、数十年にわたって続いていた戦争もようやく終結しました。
しかし、戦争によって荒廃してしまったフロンティアの地はもはや生存に耐える場所ではありませんでした。人々は新天地を求め更なる未開の土地、アウトランズへ進出していきます。
資源と可能性に満ちた辺境の地アウトランズ、そこではいつしか新たな娯楽が生まれていました。

それがApexゲーム。フロンティア中のレジェンドが富と名声を求めて集まり殺しあうデスゲームです。

元はPS4コントローラーでパイロットをやっていた僕も昔の血が騒いでしまい、今度は新たな相棒であるキーボードとマウスでレジェンドとしてApexゲームに参加しています。

そしてなんやかんやあり、仕事を辞めてレジェンドとして食っていくことを決意しました。

そう、これは退職エントリ……
てかさ、みんな「退職エントリー」とかいいつつ「次の会社はXXXです!」って書いてるけど、それってもう転職エントリーじゃない?あ、でも僕もレジェンドになるんだからこれも転職エントリか!ガハハwwww

当方は一緒にApexLegendsをプレイして僕が爪痕バッジをとれるように接待してくれるニートを募集しております。

Apex (feat. Infinite.J555) [Explicit]

Apex (feat. Infinite.J555) [Explicit]

ReactにおけるBreadcrumb(パンくず)実装のパターン

もちろんケースバイケースなんだけど、パンくずリストというのは全体のレイアウトに属していながらマウントされる要素に従属して中身が変わるという点でちょっと厄介。
具体的にどういうケースで厄介かというと、ヘッダやサイドバーなどをまとめたpage layout的なコンポーネントを大枠に作り、内部の表示をreact-routerで切り替えている場合。業務アプリとかでやりがちなんじゃないかなとおもう。

ざっくりお気持ち擬似コード。

const PageLayout = (breadcrumbs: readonly Breadcrumb[]) => {
  <Layout>
    <Header breadcrumbs={breadcrumbs} />
    <Sider />
      <Main>
        {children}
     </Main>
    <Footer />
  </Layout>
};

const Routes = () => {
  <PageLayout breadcrumbs={/* どうやってひねり出すか */} />
    <Switch>
      <Router ... />
      ...
    </Switch>
  </PageLayout>
};

はい。

まぁ色々とやり方はある。例えばRoutingされるcomponentで、都度PageLayoutを宣言するとか。ReduxのStoreと連動させるとか(ダルい)。
でもダルいよね(ダルいよね)? react-router自体の賛否はともかく、react-routerが意図してる省力化の機能活かせてないし?

さらにさらに、パンくずリストってのは「Routingそのものと密結合」な要素なので、Routingされるcomponent内部でパンくずリストの表示を制御してしまうと「子供のコンポーネントは親に関心を持たない」という鬼原則が崩れてしまう。当たり前だけどPresentationalComponentは描画以外の状態や振る舞いに依存してはいけない。
愚直にやろうとすれば他にも色々あるだろうけど、ルーティングの二重管理とかあまりやりたくない。URL変えるのめんどくさくなるし。

Reactの「親から子へ」の鉄則を守りつつ、DOM上は別の場所で描画してぇ……
はいそうです、Portalがありますね。でもPortalを直接使うとコード上にDOMが露出しちゃって抽象度に欠けますね。ということで思いつきで書いたコードがこれです。

これを使うとこんな風に書けます。

const { Zone, ExitGate, EnterGate } = createSplitGate((arg: BreadcrumbItem[]) => <AwesomeBreadcrumbComponent items={arg} />);

const PageLayout = (breadcrumbs: readonly Breadcrumb[]) => {
  <Zone portalID="awesome-id-for-breadcrumb-location">
    <Layout>
      <Header />
      <ExitGate />
      <Sider />
        <Main>
          {children}
       </Main>
      <Footer />
    </Layout>
  </Zone>
};

const Routes = () => {
  <PageLayout />
    <Switch>
      <Router ... render={routeProps => 
        <>
          <EnterGate arg={[un, duex, trois]}
          <Presenter ... />
        </>
      } />
      ...
    </Switch>
  </PageLayout>
};

はい。
ExitGate とか EnterGate だと汎用的すぎて何が何だかなんで、実運用するときはもっと明示的な名前でaliasを作ってあげましょう。今気がついたけど Enter じゃなくて Entrance のほうが適切か? まぁいいか。

「DOM構造と機能とスタイリングを分離する」ってのはデザインに凝れば凝るほど難しくなるんですが、そういうときにportaは便利なので使っていきましょうねという話でした。
ちなみにほんとは関数名はPortalにしたかったんですが、React本体の名前とだだ被りするのでSplitgateにしました。ゲーマーなら元ネタがわかるとおもうのでSplitgate: Arena Warfare行為しましょう。

以上。

You are gonna obviously need itの法則

YAGNIの原則

YAGNIの法則はご存知ですか。
You Ain’t Gonna Need It. の略で、アジャイルとかでよく言われる「いらんもん作るな」の原則ですね。

「これいるやろー」で前もって作りこまれた機能は10%しか使われないし時間の無駄だよね(10%の根拠はあるんかな)、っていうあれです。

「まだ必要じゃない」って意訳する人もいますがこれは悪い意訳です。

続きを読む