Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

クレジットカード情報の入力時になぜ有効期限も入れなければならないのか?

ネットでクレジットカード払いをする際、カード番号以外に有効期限も入力が求められます。これはなぜなのか疑問になりませんか?疑問になりますよね。 今回はそれについて考えてみました(完全に推測で書いてます)

abst (created by ChatGPT)

クレジットカード情報の入力に有効期限が必要な理由は、同じ番号のカードが複数枚存在する可能性があるためです。カード番号だけでは一意性が保証されず、有効期限を組み合わせることでセキュリティコードが一意に定まります。これにより、過去のセキュリティコードを再利用してしまう問題を防ぎます。したがって、有効期限の入力が求められるのです。

結論: 同じ番号のカードが同時に複数枚存在する可能性があるから

カード番号がもしユニークであれば、カード番号と有効期限は1対1で紐づきます。これならカード番号だけ入力してもらえば問題ありません。データベースから有効期限情報は引っ張ってこれるので。しかし、実際にはカードは有効期限が切れそうになると別のカードが送られてきます。そのため、そもそもカード番号と有効期限情報は1対1で対応してません。

また、ほかにもセキュリティコードの問題もあります。たとえば1000回カードを更新したとします。次に発行するカードのセキュリティコードはなににすればよいでしょうか?もし過去に使ったセキュリティコードを設定すると、過去にそのセキュリティコードで登録してたサービスが再びカード支払いできるようになってしまいます。

  • 4980-1234-5678-9012 123 でサービスAに登録していたとする (有効期限は入力してない)
  • 有効期限だけ異なりセキュリティコードが同じ 4980-1234-5678-9012 02/ 123 が発行されたとする
  • サービスAでカード支払いができてしまう

つまり、あるカード番号に紐づくセキュリティコードが複数あるのが問題なのです。コレに対して、カード番号+有効期限であればセキュリティコードは1つに定まります。

まとめ: カード番号のみでは主キーになり得ない

セキュリティコードを参照する際にカード番号のみだと複数枚あるときがあるので問題が発生する→カード番号+有効期限ならセキュリティコードが一意に定まる。だから有効期限も必要なんですね

TypeScript の infer は同じ名前を指定できる

(ただし有用な場面はそんなにないです)

infer に同じ名前を指定すると、ユニオン型になる

基本的に、infer に同じ名前を指定すると、それらをうまく満たすようなユニオン型になります。

以下の X1,X2,X3 はすべて number | string です。

type X1 = [number, string] extends [infer x, infer x] ? x : never;
type X2 = [number[], string] extends [(infer x)[], infer x] ? x : never;
type X3 =
  [(args: number) => number, string] extends [(args: any) => infer x, infer x] ?
    x
  : never;

関数の引数に対しては例外的な挙動をする

上に書いたように、基本的にはユニオンになるのですが、関数の引数部分で infer x を入れると異なる挙動をします。

type X4 =
  [(args: number) => number, string] extends [(args: infer x) => any, infer x] ?
    x
  : never; // never になる
type X5 =
  [(args: number) => number, (args: string) => number] extends (
    [(args: infer x) => any, (args: infer x) => any]
  ) ?
    x
  : never; // これも never になる

おそらく関数の引数が反変であることに起因しています。

TypeScript の実際のコードを読んでないので以下は僕の推察なのですが、おそらく 最初の infer x (区別するため x1 とします)と2つ目の infer x (x2) は、 x1 <: x2 かつ x1 >: x2 を満たす必要があるとか、そういう理由なんじゃないかと思ってます。ちょっと分からないのでどなたか調査お願いします。

参考

共変性・反変性とは型構築子が部分型関係をどう保ち、どう変換するかという性質のことである

デスク環境2024

去年までのもの→デスク環境変遷まとめ (2020/5 ~ 2023/1) - Panda Noir

あとから見返す用に年1くらいでデスク環境を紹介したいなと思い立ったので書きます。あと、多分ウェブフロントエンドエンジニアとしては珍しく mac と windows の二刀流構成なので、他の人の参考にもなるかも。

デスク全景

まず写真をお見せするとこんな感じです。

デスク全景

光ったりしないし壁面収納とかしてないですが、まあ最低限いい感じになってるかなと。

デスク周辺機器

  • デスク: FLEXISPOT E8B
  • キーボード: Moonlander
  • マイク: blue Yeti X
  • ウェブカメラ: Elgato Facecam
  • ディスプレイ: BenQ EW2780Q WQHD
  • モニターアーム: エルゴトロン LX デスクマウントアーム

PC は2台あります(会社の mac と私物の windows PC)。あと、Switch もデスクに載ってます。家にテレビないため仕事机に載せざるを得ないです…

Moonlander 以外はそんな凝ったもの使ってるわけじゃないです。

工夫ポイント1: 配線が綺麗

配線がきれいというか、最近配線を綺麗にしました。

ディスプレイ裏にはHDMIケーブル2本、DisplayPortケーブル1本、ディスプレイの電源ケーブル1本、ウェブカメラのUSBケーブルがまとめられています。ほぼマジックバンドでゴリ押してまとめてる感じですが。ただ、これのおかげで正面からケーブルがほぼ見えません。

ディスプレイ裏

正面からはほぼケーブルが見えない

デスク下の配線も一応いい感じにしてます。正直普段見ないのであんまガチでこだわってはないです。というか配線を工夫しなければいけないほど接続するものがないです。

デスク下の配線

あとは私物のPCとSwitch周辺は最近かなり頑張って整理しました。コードがすっきりした状態になってて満足してます。

私物PC周辺はコードが結構整理されてる

工夫ポイント2: サイドに充電系のものをまとめた延長ケーブルを設置

充電ケーブル類

クランプで電源タップを机の横に固定してます。これがすこぶる便利です。たまに出社するときに充電器を持っていく必要があるんですが、そのとき充電器が机の下側にあると取り出すのが面倒です(実際面倒でした)。そこで、サイドにおいておくようにしたんですがこれがとにかく使いやすい。あと単純に普段使いもしやすいです。

工夫ポイント3: mac と windows の切り替えが簡単

このデスク最大のポイントは、mac と windows の二刀流のしやすさです。なんとボタン1つを押すだけで切り替え可能です。 ケーブルの抜き差しも一切必要ありません。

ディスプレイは mac、windows それぞれと常にケーブルで接続されていて、入力があったほうが自動的にディスプレイに表示されるため、映像に関してはなにもする必要なく切り替えできます。

マウスに関してはそもそも mac でマウスを使ってないので切り替える必要がありません。逆にマイクとウェブカメラは windows で使ってないので、こちらも切り替える必要ありません。

キーボードだけは接続先の切り替えが必要です。キーボードは USB switcher につないであり、USB switcher の切り替えボタンを押すことで mac と windows どちらに接続するか切り替えてます。

また、キーボードにはほかにも工夫点があります。それが mac 用キーレイアウト、windows 用キーレイアウトの2種類を作って切り替えているという点です。これによって、ctrl キーなどの位置を適切に設定してショートカットキーが mac と win でなるだけ揃うようにしています。このレイアウトカスタマイズ機能があるから moonlander を使っているといっても過言ではありません。

まとめ: 現環境最高!

現デスク環境、僕としてはかなり使いやすくて満足しています。ただディスプレイが映画観るにはちょい小さいのが不満なので今モニターの買い替えを検討中ですが。

サイドデスクとかサイドのワゴンも紹介できなくはないですが、その辺は別にPC関係ないのでいいかなと。

2023年を振り返る

去年の → 2022年を振り返る - Panda Noir

仕事、趣味、プライベートについて書くぞい。

仕事、技術

  • テックリード交代した
  • 実質チーム移動になった(多分社外秘なのでどのチームかは言えない)
  • 記事をいくつか書いてバズらせた

今年は仕事に関しては特筆することないかも。チームメンバー増えたしテックリード交代したからなるべく出しゃばらないようにひたすら気配を消すようにした+チームをほぼ移動した結果そうなった感じ。でもやってることはほとんど変わってない。

記事の執筆もいくつかした。zenn で書いて4本ほどバズらせることにも成功した。でもこれがmaxかも。来年は今年以上にバズるぞ!みたいな意気込みはいまのところない。

趣味

  • 映画ばっかり見てた(200本以上)
  • 趣味グラミングはあんまやらなかった。年始とかにまとまった時間取ったくらい。
  • 合気道は引っ越す前までは結構やってたが、引っ越ししてからいけなくなった……
  • ギターはぼちぼち
  • スプラ3にハマり中

今年は趣味はほぼ映画だったな。ほかは人間との交流が趣味みたいな感じだった。

あとはスプラか。これは結構やった。2ヶ月で100時間積むくらいにはやった。でもS帯入ってから全然勝てなくなっていまちょっとモチベ下がり中。立て直したい。

あ、あと趣味カウントじゃないけど、今年は月1冊以上は本を読んでて、平均すると月1.5冊読んでた。外に出るようになって電車時間が増えたからだな(電車のなかではなるだけスマホ見ないというルールを課してる)。これは意外と良かった。まあ読んだのはほぼ小説なんだけど。

その他プライベートとか

  • 引越しをした
  • 恋愛は2敗
  • 遊びに自分から誘えるようになった
  • ダイエットに成功した(7kgちょい)

今年の抱負として「交友」を掲げていて、それは結構達成できたかも。少なくとも去年よりは土日とかに人と会うようにできた。てか引っ越ししてからフットワーク軽くなった。俺にしては結構前進している。人は人間と交流しないといけないって事実に気づくのが遅すぎたけど、着実に成長してきてはいる。

恋愛は2敗。わからね〜〜〜〜〜。まあいいや。というか恋愛に向いてない気が結構してきている。

あすけんを使ってダイエットに取り組み3ヶ月で7kg程度落とした。腹筋割りたかったんだけど、そこまではいかなかった。3ヶ月以上のダイエットは精神に来るからできないな。今は普通に飯ガッツリ食って筋トレ中。

去年たてた目標について

去年たてた目標たち

  • 引っ越したい。今の家は来年で2年目だけど、更新はしないつもり。駅から遠いんじゃあ…人を呼ぶにしても不便。
  • 転職はまだしない。
  • 仕事関係はどうだろう…来年は何がしたいかな。最近は新しい技術とかは趣味の方でまかなえばいいかと思い始めているので仕事はこのままでいいかって思ってる。
  • 結婚圧がかかり始める年齢なのでそっちも急ぎたい。
  • 英語のリスニングを、そこそこのレベルまで上げたい

引っ越しはした。しっかりと便利になったし今のところ不満点がほぼゼロ。完全に快適。最高。

仕事に関しては「精神を安定させる」「タスクを無難にこなす」を目標にすすめて無事達成できたので、当初の目標どおりいけたと思う。今までの「ピーキーでもいいから成果を出す」スタイルから「突出しなくていいから安定して成果を出す」スタイルへのシフトがそこそこ成功した。

結婚云々はむしろ焦りが消えた。来年もぼちぼちやっていきたい。

英語のリスニングは今年ほとんど時間とれなかったな……

総評

メンタルだけ抜き出すと今年もかなり波があった。でも仕事は安定できた。これは結構成長(去年は失恋後にぶち凹んで仕事に影響を出して迷惑かけたため)。来年はそもそもメンタルがブレないように軸を作っていきたい。

仕事も安定してきている。良くも悪くも。でも来年はチーム移動から始まりそう。まだ見通し立ってなくて現時点では目標立てづらい。

恋愛はまあ去年よりはうまくなってきた(?)。容姿とかも写真見ると整ってきた感じがする。来年もぼちぼち頑張りたい。

趣味はまあ来年もこの調子だと映画になりそうだな…でも本も読みたいんだよなぁ。なんとかしたい

来年の目標とか

  • 仕事はとりあえずチーム移動後もうまく回したい。まずは安定させるところを目標に動きたい。
  • 恋愛はぼちぼちやっていきたい。
  • 英語のリスニングは来年こそちゃんとやりたいかもな…

Next.js で layout をネストしたときパフォーマンスはどうなるのか?

Next.js で作ったアプリの /foo にアクセスすると app/layout.tsx と app/foo/layout.tsx の両方が適用されます。

さて、このネストされた2つの layout それぞれでデータフェッチをしていた場合、どうなるでしょうか?

  • app/layout.tsx のフェッチ完了後に app/foo/layout.tsx のフェッチが始まる
  • app/foo/layout.tsx のフェッチ完了後に app/layout.tsx のフェッチが始まる
  • 同時に app/layout.tsx のフェッチと app/foo/layout.tsx のフェッチが始まる

ぱっと聞かれて分かりますか?僕は分からなかったので リポジトリ を実際に作って検証してみました。

答え: 同時に app/layout.tsx のフェッチと app/foo/layout.tsx のフェッチが始まる

答えは 「同時に始まる」 です。 検証に使ったリポジトリ

実例

以下のコードを実行したときにかかる時間は max(getSession() の時間, fetchUserData() の時間) になります。getSession() の時間 + fetchUserData() の時間 ではありません。

// app/layout.tsx
import { setTimeout } from 'timers/promises';
import { getSession } from '@auth/nextjs-auth0';

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const user = await getSession();
  return (
    <html lang="en">
      <body>
        <h1>hello {user.name}</h1>
        <div>{children}</div>
      </body>
    </html>
  );
}
import { setTimeout } from 'timers/promises';
import { fetchUserData } from './fetchUserData';

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const data = await fetchUserData();
  return (
    <div>
      <h2>data: {data}</h2>
      <div>{children}</div>
    </div>
  );
}