✨
TypeScript satisfies と class
TypeScript 4.9 から satisfies
が登場しましたね。
satisfies と使うことで Widening を防ぎ型推論されるオブジェクトが定義できるようになります。
こちらのスライドがとても良くまとめられていて大変参考になりました。ありがとうございます。
使用例
styled-components で ui library のを作成しているときに使えそうな Util Type です。
type CSSGlobals = 'inherit' | 'initial' | 'revert' | 'unset';
// size
export type Size = Record<string, CSSGlobals | PX | EM | REM>;
type PX = `${string}px`;
type EM = `${string}em`;
type REM = `${string}REM`;
// color
export type Colors = Record<string, 'currentColor' | 'transparent' | CSSGlobals | HEX | RGB | RGBA | HSL | HSLA>;
type HEX = `#${string}`;
type RGB = `rgb(${number}, ${number}, ${number})`;
type RGBA = `rgba(${number}, ${number}, ${number}, ${number})`;
type HSL = `hsl(${string})`;
type HSLA = `hsla(${string})`;
このように宣言しておけば Colors で間違った宣言をしようとするとエラーになります。
型にメソッドを生やす
as const sastifies
を使うだけでも厳格に型をつけられ、型推論もされるようになります。
ここでさらに型にメソッドをもたせたくなってきました。
そんなときどうするか、、、
答えは単純で class
を使うです。
基本的なことですが、TypeScript には class があります。
class に値を渡せば、そこで validation をおこなったり、メソッドを追加することができます。
例えば
type Version = `${number}.${number}.${number}`;
Version には "1.2.3"
のような . 区切りの数値を文字列で指定するという方になりますが、これにバージョンアップメソッドを生やしたいときは以下のようになります。
type VersionType = `${number}.${number}.${number}`;
class Version {
value: VersionType;
private major: number;
private minor: number;
private patch: number;
constructor(value: VersionType) {
const [major, minor, patch] = value.split('.');
this.value = value;
this.major = parseInt(major, 0);
this.minor = parseInt(minor, 0);
this.patch = parseInt(patch, 0);
}
private update() {
this.value = `${this.major}.${this.minor}.${this.patch}`;
}
majorVersionUp() {
this.major++;
this.update();
}
minorVersionUp() {
this.minor++;
this.update();
}
patchVersionUp() {
this.patch++;
this.update();
}
}
const version = new Version('0.0.0');
version.patchVersionUp(); // "0.0.1"
version.minorVersionUp(); // "0.1.1"
version.majorVersionUp(); // "1.1.1"
まとめ
以上 satisifies
を使った際にふと気になって、TypeScript の class を復習したメモでした。
Discussion