d.sunnyone.org
sunnyone.org

ページ

2024-12-18

Web入門時に読んだデザインの本まとめ(復刻版)

今回は、下書きがお蔵入りになっていた、デザインを勉強するときに読んだ本のまとめがでてきたので、微調整して公開する。2014年頃にGUIアプリからWebにスイッチした際に書いたもの。基礎的な内容をメインに勉強したので、今も概ね有用と考えている。

以下からは、基本的に本文は2014年のもの、注や指定があるのは2024年のもの。勉強し始めの感想と、10年後の感想をあわせて読むと、モチベーション的に学びやすいかなと思いこのような形にする。

Webサイトなんかを作っていて、どうもデザインする部分に苦手意識があるというか、作業を進める上でネックになっている感じがしたのだけど、 「別に勉強すればいいんじゃね?」ということに気づき、デザインの本を読んで勉強してみた。そのときに読んだ本たちを一挙紹介。

自分の目標は先の通り、Webサイト/アプリを作ることだけども「Webに関する本はWebの実現方法が主体で、 見た目のデザインそのもののセオリーとかは紙のデザインの本が強くない?」と本屋さんで本を探してて思ったので、 紙ベースの書籍やフライヤーなどを作るためのデザインの本を主に読んだ。そのため、 「デザイン」と広く言っているが、プロダクトデザインやインテリアデザインみたいな話は申し訳ないが入っていない。

この記事の読み方

本の情報のほかに、私の主観で以下の内容を書いている。

  • おすすめ度
  • ジャンル: レイアウト、色彩、タイポグラフィ
  • アプリケーション: なし

ジャンルは、「この手のデザインはレイアウト、色彩、文字に分類される気がする」と思ったので、勝手に分類している。 エディトリアルデザイン的には、装丁の部分、印刷や紙についての取り扱いも知識の一ジャンルとしてある気がするが、私がフォーカスしようと思っていない部分なので、ジャンルには入れていない。

アプリケーションは、そのアプリケーションの使い方を取り扱っている書籍について、記憶に残ったものを書くことにした。べったりツールを使っていく書籍もあるが、若干触れるだけというのもあるので、 その本の雰囲気を表す一つの方向性として見てもらえるといいと思う。

日常の資料作りをサポートする、あらゆる人向けのデザイン書籍

エディトリアルデザインの入門書には、本や1枚ものを作ることを目指す本があるのは当然として、 日常的に作るものを題材にした、そもそも本だとかを作ることを目指さない本もある。 とっつきやすいものとして、こういった内容だったものをまずは紹介。

伝わるデザインの基本 よい資料を作るためのレイアウトのルール

2024リンク: 伝わるデザインの基本 増補改訂3版 よい資料を作るためのレイアウトのルール / 技術評論社
  • おすすめ度: ★★★
  • ジャンル: レイアウト / 色彩 / タイポグラフィ
  • アプリケーション: Microsoft Office

資料を作るあらゆる方面の人におすすめの書籍

デザインそのもので仕事をしていくような人たちではなく、むしろ文書、プレゼン資料やポスターのような日常的な資料を書く人たちが、伝わりやすいデザインを実現するための本。ほぼ後述のノンデザイナーズ・デザインブックのような内容なのだが、書体や題材が現在の日本人にとって馴染みのある内容で、 非常に頭に入ってきやすい。デザイナー向けの書籍と異なり、 ツールやフォントもそこにあるものを使って実現しましょう、という形になっているので、すぐ試せる。 「センスないから読みやすい資料作るの苦手だわー」と思っている人にぜひ読んで欲しい。

基本的には伝わるデザイン|研究発表のユニバーサルデザインを書籍化したような内容であるが、紙の話であり、紙のほうが読み進めやすいので本がおすすめ。

ただし、デザイナー向け書籍と比べるとあっさりと記述されているので、興味を持ったらこの後紹介しているような 本を読んでみるといいと思う。

(2024注) 流行がありそうな領域なのに、2014年発売から今でも支持されてるのすごい。

ノンデザイナーズ・デザインブック

2024リンク: ノンデザイナーズ・デザインブック / マイナビ出版
  • おすすめ度: ★★☆ (2024注: 基本★★★だけど日常資料レベルなら★★)
  • ジャンル: タイポグラフィ / レイアウト
  • アプリケーション: なし

非デザイナー向けデザイン書籍の定番

非デザイナーがデザインの話を勉強すると言ったら必ず出てくるであろうこれ。気にしない人がやってしまいがちな例を直しながら、 どういったものが読みやすく伝わりやすいのか、日常的な書類などの身近な例で解説していく。

確かに「コントラスト」「反復」「整列」「近接」という話が、非デザイナーにも伝わるようよく整理されていて読みやすい。 しかし、欧文主体でしかも作例も古い感じなので、ちょっと入ってきにくい。昔読んで、最近勉強したタイミングで また読んだのだけど、欧文の書体選びとか、後から読んだからこそ参考になった(頭に入った)感がある。 なので、読んでおく価値はあると思うけども、時間の限られたサラリーマンでも必読、という感じではないかな、という感じ。

(2024注) 改訂されているようなので、読みやすくなっているかもしれない。一度見てみると良いかも。いろいろ作ってみたあとの2024年のほうが、この本の価値を感じている。

デザイナーの勉強の書籍(基礎系)

実例がまずあってうんぬんというよりは、色は色相/明度/彩度があって、みたいな各構成要素ごとに説明していくようなスタイルで 説明されている書籍をこちらに並べている。

難しさは、先のものと同じくらいのものもあるが、安くない書体を使うことが前提だったり、印刷会社での印刷が前提だったりといった部分が 多く占めるものに関してはこちらに分類している。

タイポグラフィの基本ルール プロに学ぶ、一生枯れない永久不滅テクニック

2024リンク: タイポグラフィの基本ルール-プロに学ぶ、一生枯れない永久不滅テクニック / SB Creative
  • おすすめ度: ★★★
  • ジャンル: タイポグラフィ
  • アプリケーション: なし

文字組について易しく、しかしきっちりと解説している一冊

基本的には文字の取り扱い(書体選び、アキの話などなど)について、他のタイポグラフィの書籍同様に解説している本。 タイポグラフィの知識が全くなくても読めるレベルの読みやすさでありつつも、詳しい例を載せながらきっちりと解説している。 例えば、アキは適切に、てな感じでさらっと流す書籍も見受けられるが、本書では複数の例で、色付けしたりしてわかり 易くなるように説明されている。専門用語にはきちんとふりがなが振ってあるのもうれしい(「平体」とか)。 タイポグラフィを名乗っているが、紙面レイアウトについても触れられている。そのロジックならそれは単にやり方の一つだよね、というのを思う部分もあるわけではないが、 実例も多く読みやすいので、おすすめの一冊である。

配色&カラーデザイン プロに学ぶ一生枯れない永久不滅テクニック

2024リンク: 配色&カラーデザイン ~プロに学ぶ、一生枯れない永久不滅テクニック~ / SB Creative
  • おすすめ度: ★★★
  • ジャンル: 色彩
  • アプリケーション: なし

色の基礎知識と配色の実例について読みやすく説明。PCCSは知っておくべき

色彩調和や配色手法などの基礎知識と、Webサイトを並べて配色について説明した事例集。似たようなタイトルついてるしタイポグラフィのやつとシリーズなのかな? 色彩検定ででてくる話が一通り書いてあるのだけど、読むためのものなので問題集より読みやすいし、まぁ実例がWebサイトなので色彩検定ででてくるファッションとかインテリア/エクステリアの話より馴染みやすい。

PCCS(Practical Color Co-ordinate System:色相とトーンという二軸での色の表現)の使い方を、この本で知ったおかげで色を考えやすくなった。もっと「ちゃんと」表現できるCMYKやHSL(HSB)の状態でも、ある程度色をシステマチックに決めるための方法論を自分の中で持っていれば要らないのだろうけど、そうでなければPCCSとその使い方を知ると便利。ざっくり色を考える方式としては、自分の中で不滅だと思う。

(2024注) 2024年の今でも色を選ぶときのやりかたはこの本の発想がベースになっていて、それを便利にするために作ったpcolorsは今でも使っている。不滅の看板も伊達ではなく、とても助かっている。

デザイン解体新書

2024リンク: デザイン解体新書 / ワークスコーポレーション
  • おすすめ度: ★★★
  • ジャンル: レイアウト / 色彩 / タイポグラフィ
  • アプリケーション: InDesign / Quark Xpress / Illustrator

前提知識が必要だが、実例が非常に多く、実践的で読み応えがある一冊

実際に著者の方がデザインされた本などを題材にデザインについて解説していく一冊。 ある程度の知識があることは前提としており、いきなり読むとつまづく。 例えば「二分アキってなんだっけ?」といったように用語の方面だとか、「こっちのツメはいいけど、こっちはダメといわれても、どう違うのこれ?」という感じで、見慣れてないと違いがわからない可能性すらある(最初そうだった)。 しかし、「ああ、これが紙の世界のスタイルシートなんだ」と思うレベルに要素要素に詳しく書かれた指示と、それに対して、ただきれいだからこうしたという話ではなく、 ちゃんと理由づけて解説されているのが素晴らしい。

2006年なので、若干古さを感じなくもないが、それは置いてでも価値がある。エディトリアルデザインに興味があれば読むべき一冊。 ここに書かれている内容も、やり方の一つではあるのだと思うが、ここまで徹底解説しようとすると、そうならざるを得ない。 すでにWebデザインだとか、デザインの仕事をしていたとしても、書籍の編集に携わったことがないのであれば読んで損しないと思う。

(2024注) いまでもめっちゃ推し。違う頭があることがわかる貴重な本。

キチンと身につけたい人のためのデザインの総復習

2024リンク: キチンと身につけたい人のための デザインの総復習。 / MdN BOOKS
  • おすすめ度: ★★☆
  • ジャンル: レイアウト / 色彩 / タイポグラフィ
  • アプリケーション: InDesign / Illustrator

タイトル通り復習という感じの書籍

レイアウト、色、文字、断裁等について全般的に通して説明した本。同じように全般的に説明している「伝わるデザインの基本 よい資料を作るためのレイアウトのルール」が日常的に作成する資料にフォーカスしたのに対して、こちらは出版物を対象にすることでもう少し踏み込んだ感じになっている。フォントを自由に選びにくいといった文字に対する制約がなくなったので、特に文字についてノンデザイナー向け書籍より詳しい(Wordで1文字ずつ詰め具合を調整しろって言われても辛いものがあるものね)。紙面が前提だし、デザイナーの立場でこういうことになったらこうしてしのぐ的な話もあって、ワークフローを意識した感じ。エディトリアルデザインの分野に入っていくときに最初のころに読むとか、部分部分でやってた人が弱点を見つけるみたいなことを目指したであろうという感じの一冊。

標準DTPデザイン講座

2024リンク: 標準DTPデザイン講座 基礎編 / 翔泳社
  • おすすめ度: ★☆☆
  • ジャンル: TODO
  • アプリケーション: なし

ワークフローの勉強にはよさそう

DTPとはなんぞ、という本。こうしたらよりよいデザインになります、というよりは、こうやって進めていきます、こういうのを使います、という感じの本。 デザインとしてはあまりよくない例があるように思うので、読むのであれば、細かいことは気にせず大枠こんなか、という読み方をすればいいと思う。「CTPってなんだっけ?」とか「校正のフローはこんな感じ」か、みたいな知識的な側面で読むと参考になるとは思う。 なお、2004年と古いので、しょっちゅう変わるものの話についてはあまり役に立たない。PCのスペックとか。

TYPOGRAPHY 2014/05

  • おすすめ度: ★★☆
  • ジャンル: タイポグラフィ
  • アプリケーション: なし

文字が大好きな人たちが書いてることがわかる雑誌

読むほど文字が好きな人たちが書いてるんだろうなってことが伝わってくる。文字について学ぼうと思っていたときに、特集「楽しく学ぶ文字入門」という表示を見かけ読んでみた。この特集はよく書かれており、本当はこれを万人におすすめに入れようかと思ったが実作業的な側面では 「タイポグラフィの基本ルール」のほうが読みやすく、例も多いのでやめた。とはいえ「フォントの見分け方」など、作業とは別の観点ではあるが、 よくでてきそうな疑問について書かれている。何より文字に対する愛が伝わってくるのがよい。買って損はない号だと思う。

(2024注) 雑誌のものを今取り上げなくていいとも思ったのだけど、文字が好きな人がいるっていうのは自分のなかで新鮮な学びだったので、そう思ったときのテキストを残した。ピンポイントでこの本じゃなくても、そういう想いのある本を読んでみると、新しい世界が見れるかも。

デザインのルール、レイアウトのセオリー。

デザインのルール、レイアウトのセオリー。 / MdN Books
  • おすすめ度: ★★☆
  • ジャンル: レイアウト / 色彩 / タイポグラフィ
  • アプリケーション: なし

レイアウトの観点のまとめ

「対称性」「統一感」「メタファー」など、挙げる観点に対して、実際の例や作った例を出して、その価値について解説していく本。 読み進めて難しくはないので、レイアウトが生み出す価値を知っておくという意味で、先に読んでおく側に分類してもよかったのだけど、 実例ベースでの解説であるし、どのような構成要素があるか知っていないと、価値が薄れてしまうかなという意味で、応用編に分類した。 作っているときに、この観点で考えたかな、という意味でチェックポイントとして良いのではないかと思った。

Design Rule Index[第2版]― デザイン、新・25+100の法則

(2024注) 結構いい本だったと思うのだけど、タイトルしか下書きになかったのでタイトルだけ紹介。

その他デザイン関連書籍ピックアップ

上述のものより、ジャンルを絞ってピンポイントで書いているような本を取り上げる。3つのジャンル分けは広すぎるものもあるので、特にしない。

たのしいロゴづくり -文字の形からの着想と展開

2024リンク: たのしいロゴづくり / BNN
  • おすすめ度: ★★☆

タイトルの通り。文字からどうやってロゴにしていくか、そのアイデア集のような感じ。

Photoshop+Illustrator Design Technique

2024リンク: Photoshop + Illustrator Design Technique / 翔泳社
  • おすすめ度: ★☆☆

作例がいくつも載っていて、どうやってそれを作っていくか、というのを説明した本。ツールの使い方のチュートリアルというよりは、 どういったテクニックを使っていくか、というお話。

たのしいインフォグラフィック入門

2024リンク: たのしいインフォグラフィック入門 / BNN
  • おすすめ度: ★★☆

図解するとはどういうことか、どうやって進めていけばいいか、という本。

プロになるためのWebデザイン入門講座 実践で役立つPhotoshop&Illustrator徹底ガイド

2024リンク: プロになるためのWebデザイン入門講座 実践で役立つPhotoshop&Illustrator徹底ガイド / 技術評論社
  • おすすめ度: ★☆☆

Webデザインの用途でPhotoshopの使い方を説明した本。悪くはないと思うけども、Webの「PhotoshopでWebデザインをはじめよう! 」のほうが読みやすいかなーといったところ。

おわりに

当然の話だけど、こうして読んできても、すぐに美しいデザインができるようになったりはしない。 やっぱり経験だな、というのが感想。でも逆に言うと、天才の粋に行かなければ、経験なのかなと思う。環境という話も大きいと思うけども。

読んできて全く役に立たなかったかというと、そんなことはなく、いい悪いとはどういうことか、というのが読む前と比べるとかなり見えるようになったと思う。 そういった意味では、方向性が少しは見えるようになったという意味で、読んできて間違いなく正解だった。 実用性という意味でも、デザイナーの意図が汲み取りやすくなったので、作りやすくなったと感じている。

なお、これを見て「それ読むならこれ読んで!」てな本があれば教えてもらえれば読もうと思うので、おすすめがあればぜひ教えてください。


2024年に読んで

「やっぱり経験だな」というのは、実践で学ぶことが多いという意味で、それはそうと思うのだけど、この本たちを読んでいたおかげで助けられたという場面はかなりあった。この10年の間に、作り運用してきたプロダクトたちの中には自分が表層まで手掛けてきたものもいくつかあるのだけど、使いやすいという評判も頂いている認識で、それはこのときの学習の影響が多分にあると思う。10年前に勉強しておけばよかったなと思うことはよくあるけど、これは10年前に勉強してよかったと思える類だなと、当時の10年後から振り返って思った。

(ブログのデザインがボロボロなことにも気づいてしまったのでなんとかしたい)

2024-11-25

exiftoolとpolarsでよく撮っている焦点距離を調べる

スマホを買い替えて以来、カメラで撮るよりスマホのほうが撮りやすいところあるなあと思っていたのだけど、いまさら焦点距離の微妙な違いが影響しているのではないかと気づいたので、カメラ購入以来控えてきたレンズ購入を検討することにした。キットレンズで行けるところまで行こうと思っていたがついにこのときが来てしまった。

カメラのレンズはSONY FE 28-60mm F4-5.6なので、28mmスタート。スマホはPixel 8 Proで1xが24mmらしい。先の困り具合から24mmは必要ということがわかる。しかし、24mmで十分かはわからない。単焦点で良いのか?ズームのほうが良いのか?そこで実際に撮っている写真からどのあたりをよく使うのか調べてみることにした。

ステップ1: exiftoolで写真ファイル群から焦点距離を収集する

写真のファイルに付与されたEXIF情報にレンズや焦点距離は記録されている。このEXIF情報を取得するツールは様々あるが、exiftoolを使うとコマンドラインで取得することができる。

コマンド例は以下のとおり。

$ exiftool -LensId -FocalLength -csv -ext jpg 20230103-浅草
SourceFile,LensID,FocalLength
20230103-浅草/DSC04803.JPG,Sony FE 28-60mm F4-5.6,35.0 mm
20230103-浅草/DSC04799.JPG,Sony FE 28-60mm F4-5.6,28.0 mm
20230103-浅草/DSC04818.JPG,Sony FE 28-60mm F4-5.6,28.0 mm
20230103-浅草/DSC04814.JPG,Sony FE 28-60mm F4-5.6,35.0 mm

exiftoolはファイルだけでなくディレクトリも引数に撮ることができ、-ext jpgとすると拡張子の絞り込みまでできる(ARWとどっちかで良いので)。さらに、-csvでCSV出力にできるし、-LensIdと-FocalLengthのようにフィールドを限定することもできる。

1ファイルを指定するとすべての情報を出すくらいの機能しかないと思っていて、シェルスクリプトでも書いて回すかと思っていたのだが、コマンド一発で済んでしまった。

ステップ2: polarsで集計する

sqliteに入れてもよかったんだけど、Polarsというものが使われているらしいのでせっかくなので試してみた。PandasみたいなノリだけどSQLも受け付けるらしい。

インストールはpip install --user polarsで入れた。

$ ipython3
Python 3.10.12 (main, Nov  6 2024, 20:22:13) [GCC 11.4.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.31.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import polars as pl

In [2]: pl.Config(tbl_rows=10000)
Out[2]: <polars.config.Config at 0x7e5fd1f90400>

In [3]: df = pl.read_csv('/tmp/summary.csv')

In [4]: df.sql("""
   ...: WITH s AS (SELECT LensID,FocalLength,count(*) AS count FROM self GROUP BY LensID,FocalLength ORDER BY FocalLength),
   ...: a AS (SELECT count(*) as total FROM self)
   ...: SELECT s.LensID, s.FocalLength, s.count::float * 100 / a.total AS percent FROM s CROSS JOIN a
   ...: """)
Out[4]: 
shape: (33, 3)
┌────────────────────────┬─────────────┬───────────┐
│ LensID                 ┆ FocalLength ┆ percent   │
│ ---                    ┆ ---         ┆ ---       │
│ str                    ┆ str         ┆ f64       │
╞════════════════════════╪═════════════╪═══════════╡
│ Sony FE 28-60mm F4-5.6 ┆ 28.0 mm     ┆ 59.369925 │
│ Sony FE 28-60mm F4-5.6 ┆ 29.0 mm     ┆ 3.150373  │
│ Sony FE 28-60mm F4-5.6 ┆ 30.0 mm     ┆ 2.143553  │
│ Sony FE 28-60mm F4-5.6 ┆ 31.0 mm     ┆ 2.273465  │
│ Sony FE 28-60mm F4-5.6 ┆ 32.0 mm     ┆ 2.208509  │
│ Sony FE 28-60mm F4-5.6 ┆ 33.0 mm     ┆ 1.52647   │
│ Sony FE 28-60mm F4-5.6 ┆ 34.0 mm     ┆ 1.721338  │
│ Sony FE 28-60mm F4-5.6 ┆ 35.0 mm     ┆ 2.53329   │
│ Sony FE 28-60mm F4-5.6 ┆ 36.0 mm     ┆ 2.143553  │
│ Sony FE 28-60mm F4-5.6 ┆ 37.0 mm     ┆ 1.85125   │
│ Sony FE 28-60mm F4-5.6 ┆ 38.0 mm     ┆ 2.208509  │
│ Sony FE 28-60mm F4-5.6 ┆ 39.0 mm     ┆ 1.753816  │
│ Sony FE 28-60mm F4-5.6 ┆ 40.0 mm     ┆ 1.623904  │
│ Sony FE 28-60mm F4-5.6 ┆ 41.0 mm     ┆ 0.779474  │
│ Sony FE 28-60mm F4-5.6 ┆ 42.0 mm     ┆ 0.974342  │
│ Sony FE 28-60mm F4-5.6 ┆ 43.0 mm     ┆ 0.779474  │
│ Sony FE 28-60mm F4-5.6 ┆ 44.0 mm     ┆ 0.876908  │
│ Sony FE 28-60mm F4-5.6 ┆ 45.0 mm     ┆ 0.84443   │
│ Sony FE 28-60mm F4-5.6 ┆ 46.0 mm     ┆ 0.552127  │
│ Sony FE 28-60mm F4-5.6 ┆ 47.0 mm     ┆ 0.389737  │
│ Sony FE 28-60mm F4-5.6 ┆ 48.0 mm     ┆ 0.129912  │
│ Sony FE 28-60mm F4-5.6 ┆ 49.0 mm     ┆ 0.584605  │
│ Sony FE 28-60mm F4-5.6 ┆ 50.0 mm     ┆ 0.422215  │
│ Sony FE 28-60mm F4-5.6 ┆ 51.0 mm     ┆ 0.032478  │
│ Sony FE 28-60mm F4-5.6 ┆ 52.0 mm     ┆ 0.324781  │
│ Sony FE 28-60mm F4-5.6 ┆ 53.0 mm     ┆ 0.16239   │
│ Sony FE 28-60mm F4-5.6 ┆ 54.0 mm     ┆ 0.519649  │
│ Sony FE 28-60mm F4-5.6 ┆ 55.0 mm     ┆ 0.16239   │
│ Sony FE 28-60mm F4-5.6 ┆ 56.0 mm     ┆ 0.032478  │
│ Sony FE 28-60mm F4-5.6 ┆ 57.0 mm     ┆ 0.16239   │
│ Sony FE 28-60mm F4-5.6 ┆ 58.0 mm     ┆ 0.129912  │
│ Sony FE 28-60mm F4-5.6 ┆ 59.0 mm     ┆ 0.584605  │
│ Sony FE 28-60mm F4-5.6 ┆ 60.0 mm     ┆ 7.047743  │
└────────────────────────┴─────────────┴───────────┘

サブクエリで怒られたのとFROMにカンマ区切りにしたら怒られたから書き換えたけど、それ以外は自然に書けた。CTEも使えるしすごい。

端以外はサマってみたいので、polarsのやりかたも使ってみる。

In [80]: s2 = s.filter(pl.col("FocalLength").is_in(["28.0 mm", "60.0 mm"]).not_())

In [81]: s3 = s2.select(pl.col("percent"), pl.col("FocalLength").str.extract(r"^(\d)", 1).alias("T"))

In [82]: s3.group_by("T").agg(pl.col("percent").sum())
Out[82]: 
shape: (4, 2)
┌─────┬───────────┐
│ T   ┆ percent   │
│ --- ┆ ---       │
│ str ┆ f64       │
╞═════╪═══════════╡
│ 3   ┆ 20.363754 │
│ 5   ┆ 2.53329   │
│ 2   ┆ 3.150373  │
│ 4   ┆ 7.534914  │
└─────┴───────────┘

filter()とかselect()にはpl.col("name")を使って何かする。これはpolars.Exprpolars.Expr.strを見ればいいっぽい。 

結果を見て

集計した結果以下がわかった。

  • 28mmが約60%。めちゃ使う。
  • 29mm〜40mmはそれぞれ1%以上ある。まあまあ使うらしい。
  • 41mm〜59mmは1%未満。あまり使わないみたい。
    • 30mm台をまとめて20%, 40mm台は7.5%
  • 60mmは約7%。
24mm単焦点でも困らないかもしれないが、40mmまであると便利そうというところか。この結果を見つつ検討したい。

2023-12-19

例でわかるTypeScript Utility Types

これはTypeScript Advent Calendar 202319日目の記事です。例とともにUtility Typesの紹介をします。

Utility Typesとは

Utility Typesは、型から型を生成するためのTypeScript組み込みの型です。ライブラリを書いているような方ならば普段から使っていると思いますが、Utility Typesが何かわからない方もPartial<Foo>やRecord<string, string>なんかは見たことがあるのではないでしょうか。

どんなものがあるか?というのはドキュメントを見てもらえれば良いので、 詳細はそちらに譲りますが、今日はどういうときに便利なのか?という視点でUtility Typesの主要なものを分類しつついくつか紹介します。

TypeScriptが提供する型: 作るもの

Record<Keys, Type>

Recordは、Keysをキーとするプロパティを持ち、そのプロパティの値の型はTypeであるという型を生成する型です。これは主にデータを格納するためのオブジェクトの型を定義するときに使います。

type FooRecord = Record<"prop1" | "prop2", string>;
// → { prop1: string, prop2: string }

上記のようなケースだとベタに定義したほうが良いのでありがたみはないですが、keyの集合がすでに定義されている場合は便利です。

interface BarData {
    prop1: string;
    prop2: number;
    prop3: Date;
}

type BarDataErrors = Record<keyof BarData, string>
//  → { prop1: string, prop2: string, prop3: string}
stringのように広い型を指定することもできます。 
type StringRecord = Record<string, string>;

もともとRecordは

type Record<K extends keyof any, T> = {
    [P in K]: T;
};

と単純なのでこれを書いてもいいのですが、意図を明示できる上に簡潔に記述することができます。

TypeScriptが提供する型: 主にプロパティを加工するためのもの

Pick<Type, Keys> / Omit<Type, Keys>

PickはTypeのプロパティをKeysに絞った型を作ります。OmitはTypeのプロパティからKeysを外した型を作ります。ホワイトリストとブラックリストですね。

これらの使い方は幅広いのですが、既存の関数のラッパーを作るときに便利です。

例えば、ButtonというReactコンポーネントがあり、propとしてsizeを取るとき、このsizeを“large”に固定したLargeButtonというコンポーネントを作りたいようなケースを考えます。このときにLargeButtonのpropsの型をButtonからsizeプロパティを外したものとして作ると、Buttonと同じだがsizeは渡せないということを明確にすることができます。

type LargeButtonProps = Omit<ButtonProps, "size">;

function LargeButton(props: LargeButtonProps) {
    return <Button {...props} size="large" />
}

Extract<Type, Union> / Exclude<UnionType, ExcludedMembers>

ExtractはTypeからUnionに代入可能なものを取り出した型を作り、ExcludeはUnionTypeからExcludedMembersに代入可能なものを外した型を作ります。

これは、discriminated unionとあわせて使います。例えば、type: “success”のときは正常、type: “error”のときはエラーであるResultオブジェクトを考えます。

interface ResultSuccess {
    type: "success";
    data: Record<string, string>;
}

interface ResultError {
    type: "error";
    errorMessage: string;
}

// 既存ライブラリが合わさっている型だけexportしていたり
export type Result = ResultSuccess | ResultError;

このような場合に、ExtractやExcludeを使うと限定した型を得ることができます。

type SuccessType = Extract<Result, {type: "success"}>
// ResultSuccess
type NonSuccessType = Exclude<Result, {type: "success"}>
// ResultError

Partial<Type> / Required<Type>

Partialはプロパティを任意にし、Requiredはプロパティを必須にします。

Partialは例えばプロパティを部分的に受け取ってオブジェクトを更新するような関数を作る場合に使えます。

function updateFoo(foo: Foo, fields: Partial<Foo>) {
    return {...foo, ...fields };
}

もともとすべてのプロパティがrequiredとは限らないので、Partialと比べるとRequiredを素で使うケースは少ないと思いますが、他との組み合わせ、例えばPickで明確にして使う、ということもできます。

interface Foo {
    name?: string;
    age?: number;
    description?: string;
}

type Bar = Required<Pick<Foo, "name" | "age">>;

NonNullable

NonNullableはTypeからnullとundefinedを外します。

type NullableType = string | null;
type NonNullType = NonNullable<NullableType>;
// string

まあこれはわかりやすいですよね。

TypeScriptが提供する型: 関数に関するもの

関数の型に対して何かをする型は、汎用的に関数を取ってそれをどうにかする関数には不可欠なものですが、具体的な関数がわかっている場合にも以下のような使い方をすることができます。

ReturnType

ReturnTypeは関数の型から戻り値の型を得ます。

ReturnTypeは、関数はわかっているが型にアクセスできない、または定義されていないようなとき、例えばfactory的な関数でその型の明示がないようなケースのときに、その値を中継するなどのことをするために型が欲しいときに便利です。

function createFoo() {
    return {
        a: "abc",
        b: 123
    };
}

type CreateFooReturn = ReturnType<typeof createFoo>;
// { a: string, b: number }

Parameters

Parametersは、関数の引数の型を得られます。ラッパー関数を作るような場合に、既存の関数の型をそのままに引数を足したいなどのときに便利です。

function foo(a: string|number) {
    return a;
}

type FooParameters = Parameters<typeof foo>;
function wrappedFoo(a: FooParameters[0], b: string) {
    other(b);
    return foo(a);
}

Awaited

asyncな関数だとreturn typeがPromiseになりますが、そのままでは扱いにくいです。 そんなときにAwaitedを使うと剥がすことができます。

interface Foo {
    a: string;
    b?: number;
}

export async function createFoo(): Promise<Foo> {
    return {
        a: "bar",
        b: 123
    };
}

///

type RequiredFoo = Required<Awaited<ReturnType<typeof createFoo>>>;
// {a: string, b: number}

自分で作る

Utility TypesもTypeScriptで定義された型でしかないので、このような型は自分でも作ることができます。

例えば、部分的に任意にするPartialPartiallyというものを作ると以下のようになります。

// すでに定義されているHoge
interface Hoge {
    name: string;
    description: string;
    startAt: Date;
    finishedAt: Date;
}

type PartialPartially<T, K extends keyof T> = Partial<Pick<T, K>> & Pick<T, keyof Omit<T, K>>;
// 終わってない(finishしていない)かもしれない型を作る
type HogeMayUnfinished = PartialPartial<Hoge, "finishedAt">;

このように、型の操作の仕方と、型の操作そのものを分離しておくと、あとから見たときの悩み度合いが減って良いです。

おわりに

使わないに越したこともないものもありますが、どうしようもないときは知ってるか知らないかで型の扱いの難易度が変わってきます。

Utility Typeを使って、型操作を楽にしていきましょう。

2023-03-27

PHPerKaigi 2023に参加してきました

YAPC::Kyoto 2023を見て、PHPの世界をまた見てみるのいいかもと思ってPHPerKaigi 2023に行ってきました。結果、今のPHPを知れたという意味でもよかったし、ああいう雰囲気の場所が戻ってきたんだというのをまた体感できたという意味でもよかったです。スタッフの皆様、参加者の皆様お疲れ様でした。

以下、セッションのメモです。

---

勉強になったセッション

勉強になったのはこの「PHPの配列の内部実装について学びたくなった。

PHP4のときにガラケー向けアプリケーションを書いていて、arrayの性能に悩まされたことがあり、あのarrayはなあと思っていたのだけど、今更ではあるもののPHP7で真の配列が導入されたことをここで知れたのでよかった。

印象に残ったセッション

印象に残ったのは「名付けできない画面を作ってはならない - 名前を付けるとは何か

設計の話をするセッションだと思っていたのだけど、もうちょっと広く見ていてなるほどなと思った。気持ちの面も結構大事な話だと思う。

2023-03-21

YAPC::Kyoto 2023に参加してきました

京都観光も兼ねて、YAPC::Kyoto 2023に参加してきました。面白かった。遠征でのカンファレンスの参加は人生初なので、そういう意味でも新鮮な体験だった。

印象に残ったセッション

みんな面白かったのだけど、印象に残ったのはmacopyさんのデプロイ今昔物語だった。


よくわからないホスティング環境を借りてPHP(確か4だったと思う)のプログラムを「ホームページ」に置いてみたりとか、読めないPerlを書いて自分で困ったりしていた時代を思い出して、原点に帰った気分になれてとてもよかった。

遠征での学び

日曜日にYAPCで、京都にせっかく行くのだから土曜日は観光しようと決めていて、土曜日に観光するなら朝から行けたほうがいいよねということで金曜日に行って泊まり、日曜日遅くなるかもしれないから月曜日に帰ろうということで、結果3泊4日になった。歩数計を見ると40km近く歩いていることになっているので、結構満喫したと思う。

旅程に合わせてホテルを変えたので、服は洗濯しちゃえば運ぶの楽じゃないか?と思ってチャレンジしてみたものの、旅から帰ってきたあとコインランドリーに行き来して洗濯するのは結構しんどいというのは学びだった。洗濯と乾燥が一緒ならいいのにな~

荷物まわりはuzullaさんがテクニックをまとめてくれているので、今度参考にして楽をしたい。

俺的!遠方カンファレンスの参加体験向上テク 2023最新版 - uzullaがブログ https://uzulla.hateblo.jp/entry/2023/03/21/132421


2022-12-31

自室作業環境再構築(2022)

もともとリモートワーク的に作業する環境はあったものの、机にガタが来たのをきっかけに見直しをして作り直したので、その環境のメモ。もう数ヶ月前なのでちょっと情報が古かったりするのだけど、部屋の環境を作るときの参考になれば。

家具

デスク: FlexiSpot E8 (+ 120cm 天板)

まずはデスクから。今までのデスクはキーボードの棚を引き出して使って、上にプリンタ棚があるいわゆるPCデスクという感じ。地震でキーボードの棚が引き出せなくなったことをきっかけにサイズを測ってみたら幅100cm/奥行き50cmしかなくてなるほどこれは狭いなと。

いっそデスクは新調しようということで調べてみると、高さが調整できたほうが良さそうだなというところには来て、電動昇降をありにするか迷っていたのだけど、使っている人にヒアリングしてみると、ずっとそこで仕事するなら切り替えになって良いという話を聞いたので、まあ机はケチるところではないし買ってみようかと思い電動昇降つきを選択。

機種としては、昇降デスクの定番らしいFlexiSpotのメインストリーム系であろうE8を選択。120cm天板/ウォールナット色をセットで追加。

実際に使ってみると、新しい体験で面白かった。スタンディングであまり作業してはないのだけど、細かい調整が気軽にできたり、配線なんかのときに持ち上げて作業できるのは嬉しい。どの程度活用されていくかは未知数だけど、らしい使い方を探していくことを含めて楽しそうだと思う。

ちょっとがっかりだったのがウォールナットの色がだいぶ赤っぽかったこと。現物を確認できなかったので、仕方がないけど、暗めの茶色にしたかったので、セットだと他の選択肢はなかった。結局電動ユニットやコントローラは木ねじで止めるので板はなんでもよく、こだわるならかなでものというところの天板を合わせるのがテンプレみたい。サンプルを注文できるみたいだし、選ぶ手間とコスト感が合えばそのほうがいいかも。ホームセンターで板を買ってきてDIYする人もいるらしい。

あとは幅について。100cmから120cmになってだいぶよくなったが、まだちょっと狭い。140cmを置けないことはなかったから140cmにしたほうが良かったかなと思いつつ、今の環境だと無理やり感出るからこれでもよかったかな、みたいな、サイズに関してはちょっとモヤっとする感じになってはいる。奥行きについては10cm伸びたのと、モニターアームをつけたこともあって結構いい感じにはなった。

PCワゴン: 30cm✕60cmで天板が昇降するやつ

PCは台車に乗せてデスクの下に置こうと思ったのだけど、120cmの幅だとだいぶ狭くなってしまう。仕方がないので横に置くことにしたのだけど、PCの上が棚になっていれば実質デスクを幅広く使えるのでは?ということで、天板を昇降できるPCワゴンをAmazonの森をかき分けて探してきた。結果座っている側の高さにあわせるといい感じにデスクを延長できている。

下に入れる場合でもPCワゴンいろいろあるみたいだから、フィットするのを探してみるのもいいかも? 

ケーブルトレー: クランプ式/ワイヤータイプの40cm✕2セットのもの

デスクが昇降するので、卓上↔床の配線はなるべく少なくしたい。となると、天板側になんとかしてケーブルを持ってくる必要がある。そのためにケーブルトレーというものがあって、形がいろいろあるのだけど、こだわりがないので、Amazonの森をかき分けて2個セットなのにセールで1.5kというものを見つけたので購入。

手軽そうだったのでクランプ式を選んだのだけど、どうせネジ止めしているので、ネジ式でも良いとは思う。ただ、モニターアームのクランプと干渉しない位置に設置する必要があるので、そのときに融通が効きやすいものを選択するのが良いとは思う。

椅子:REC-128AX

20年前くらいに買った手動昇降つきでメッシュ背面なオフィスチェア。いいやつがあれば置き換えるかもしれない。

長く使っているから座面の合皮がやぶれてはがれてしまったのだけど、合皮補修シートを使って直したらいい感じに戻った。

タイルカーペット: サンゲツ スタイルキットループ

昔から使ってたニトリの安いパズルマットと比べると圧倒的に良くて、ずれないし質感も良い。素直におすすめできる。

定価は40x40で800円/枚くらいだけど、楽天で500円/枚くらいのところがあった。サンプルも送ってもらえるので、試してみると良いかも。

デスクの寿命から派生した環境再構築のPCまわり編。デスクが変わったので、PCまわりもいろいろ不便だった部分を直した。

PC周り

モニタ: I-O DATA LCD-GCWQ341XDB

モニタは34インチ ウルトラワイドモニタ(UWQHD: 3440x1440)を選択。これは正解だった。

モニタは6年くらい前に買った27インチ4Kのモニタ(LG 27UD58P-B)と15インチ4Kのモバイルディスプレイを使っていたのだけど、27インチ 4K はdot by dotで使うと163ppiと、21インチ フルHDの105ppiと比べると圧倒的に細かくてスケーリングしないと使えない。

現実的に使おうとするとWQHD (2560x1440) 相当が109ppiなので、150%スケーリングしたいところなのだが、XOrg環境はまだ浮動少数スケーリングが得意じゃないので、200%でフォントサイズを調整して使っていた。

フルHD (1920x1080)x3の環境に慣れているので、なるべく広く取りたいのだけど、4Kも 200% にするとフルHDになってしまって、全く広くなくなっていた。

24インチ WQHD(2560x1440)を2つ並べるか?いや122ppiは細かすぎる、WUXGA (1920x1200)を2つしかないか?などと考えていたところ、34インチ UWQHD(3440x1440)の存在に気づき、選択した結果ちょうどいい感じになった。

湾曲でないほうがいいかなと思ったのだけど、使ってみてるとそんな困らない気もする。経験したので、今選ぶならまた違った選択肢になりそう。

サブモニタ: EVICIV 15.6インチ モバイルディスプレイ 4K

前に買ったやつを34インチモニタの上につけている。チャットアプリやターミナルを置いたりしているが、必要なときに見上げて使うのはちょっと辛いのでなんとかしたいところ。

モニターアーム(メイン用): エルゴトロンLX

悩むくらいならこれ選んでおけという感じで出てくるが、実際使ってみて納得。 強いし、調整もしやすい。あまり動かさないからこれでなくてもいいのではとも思うけど、わざわざ他を選ぶほどのことでもない印象。

モニターアーム(サブ用): Bracwiser PCモニターアーム + エルゴトロン クイックリリースブラケット

モバイルディスプレイ用のアーム。重いものではないから安いやつでいいものの、メインモニタの上に配置するから高さがあるものということで選んだ。ただ、モバイルディスプレイはヘッドレスなPCのメンテ用でもあるからモニタ側に取り外し可能にするブラケットをつけて外せるようにした。

スピーカー: EDIFIER R19U2

今まで使っていたスピーカーは置きにくくケーブルの取り回しが大変で、もうちょっと音がいいやつが欲しいなと思ったのでリーズナブルで便利そうなやつを買った。4000円くらいなので音はすごくいいわけではないけど、この値段なら納得できるし、見た目も悪くない。 Amazonを見たら一緒に比較検討してたJBL Pebblesが6264円なので、たいていはこっちでいいと思う。音質はこっちのほうが良い。ただ、スピーカー本体にボリュームノブがついてないので、その意味ではR19Uのほうが便利。

マイク: マランツ M4U

昔から使っているもの。マイク〜って形をしている。 3000円くらいのくせに、もろもろの付属なんかに比べるとずっと音質が良いのでおすすめ。

マイクスタンド: anctarc マイクスタンド

USB Type-C 充電器: Baseus PD 充電器 65W 6-IN-1 1250W 電源タップ

机の上にUSB PDの口とAC 100Vの口を出すために買った。サイズ感、配置の安定感なんかがよくてこれは正解。65Wで十分かどうかは注意だけど、足りないなら100Vの口から増やすのもあり。

USBハブ: ORICO USB3.0 ハブ 4ポート

これはハズレ。クランプで止めるのはいいけど、やっぱりバスパワーはつらそう。デバイスの認識がぱたぱたする。

工具

電動ドリル: makita DF033DZ

FlexiSpotは電動ドリルで木ねじを締めることを期待しているので、電動ドリルを買った。makitaの掃除機を持っていて、そこで10.8Vのバッテリーを使っているので、それに合わせてmakitaの10.8Vバッテリーを使う電動ドリルを買った。ご家庭にmakita色のものが増えるのは不思議な感じだけど、安心感がある。

makitaの工具的には14.4Vバッテリーが今の主力のようで、バッテリーの前提がなければそこから選ぶのが良いと思う。3kくらいの安いやつを選んでしまっても良い気もするけど。

今までの机を解体するときに便利かなと思って買った六角ドリルピットがほかでも使えてすごく便利だった。併せて買うと良いかも。

作業

デスクまわりほぼ一式作ったのでだいぶ疲れた。本当は既存環境も一応維持してBlue/Green的に構築しようと思ったのだけど、作業エリアのことを考えてなくて、結局復帰までPCまわりが使えなくなってしまった。

一気に注文したわけではなく、順番に頼んでいったのだけど、出来上がっていくのを見ながら軌道修正できたのでこれは正解だった。例えばPCワゴンなんか最初の設計にはなかった。建築にアジャイル要素は難しいよなと思っていたのだけど、活きる部分もあるなと思った。翌日到着するいまの通販インフラさまさまだけど。

参考

 設計にあたりリモートワークとスタンディングデスクや周辺事情 - tech.guitarrapc.cómには大いに参考になった。感謝。

 

2022-11-03

PulseAudioのデバイス接続時自動切替とデフォルト入出力の設定

Ubuntuを再起動すると入力デバイスが変わって音が拾えなくなる問題が起きていたのだけど、デバイス接続時にPulseAudioがデフォルトデバイスを自動切り替えする機能を切ればよくなりそうなので、無効にする方法をメモしておく(この環境では結果的にUSBオーディオデバイスがいくつもぶら下がっている形になっているので、認識順やつないでいる状態で順番が変わったりするのだと思う。バスパワーのハブにつながったカメラが怪しい)

PulseAudio 自動切り替えの無効化

自動切り替えを無効化するには、/etc/pulse/default.pa のmodule-switch-on-connectの記述をコメントアウトする。

### Use hot-plugged devices like Bluetooth or USB automatically (LP: #1702794)
##.ifexists module-switch-on-connect.so
##load-module module-switch-on-connect
##.endif 

デフォルト入出力デバイスの設定

これの前はデフォルトの設定を変える方法を試していたので、それも併せてメモしておく。

1. デバイスのnameを探す

汎用的には、pacmd list-sources / pacmd list-sinks でデバイスのname:を探す。
$ pacmd list-sources
(略)
  * index: 8
        name: <alsa_input.usb-C-Media_Electronics_Inc._MARANTZ_M4U_20190520-00.mono-fallback>
(略)

ここで出てきたname: を後で使う。アスタリスクは今デフォルトに選ばれているもの。

GNOMEの設定の「サウンド」で選択していれば、pactl get-default-source / get-default-sinkでも得られる。

$ pactl get-default-source
alsa_input.usb-C-Media_Electronics_Inc._MARANTZ_M4U_20190520-00.mono-fallback

2. 設定ファイルに記述する

/etc/pulse/default.pa.d/00-default-device.conf に以下のように記述する。
set-default-source alsa_input.usb-C-Media_Electronics_Inc._MARANTZ_M4U_20190520-00.mono-fallback
set-default-sink alsa_output.usb-Resonessence_Labs_Resonessence_Labs_HERUS-00.iec958-stereo
なお、pactlコマンドでも変えることができるので、シェルスクリプトに書くのも可。
$ pactl set-default-source alsa_input.usb-C-Media_Electronics_Inc._MARANTZ_M4U_20190520-00.mono-fallback

参考

安定のArchWiki。

PulseAudio/サンプル - ArchWiki