オブジェクトの値に対する[[パターンマッチ]]を行うケース。
```ts
import { match } from "ts-pattern";
type HumanA = {
type: "A";
name: string;
age: number;
};
type HumanB = {
type: "B";
name: string;
};
type HumanC = {
type: "C";
name: string;
location: string;
};
type Human = HumanA | HumanB | HumanC;
function getRandomHuman(): Human {
const types: Human[] = [
{ type: "A", name: "Alice", age: 30 },
{ type: "B", name: "Bob" },
{ type: "C", name: "Charlie", location: "New York" },
];
return types[Math.floor(Math.random() * types.length)]!;
}
const greetingMessage = match(getRandomHuman())
.with(
{ type: "A" },
(human) => `Hello ${human.name}, you are ${human.age} years old!`,
)
.with({ type: "B" }, (human) => `Hi ${human.name}, nice to meet you!`)
.with({ type: "C" }, (human) => `Hey ${human.name} from ${human.location}!`)
.exhaustive();
```
## 条件の一部を再利用する
[[P.select (ts-pattern)|P.select]]を使う。
```ts
import { match, P } from "ts-pattern";
type HumanA = {
type: "A";
name: string;
age: number;
};
type HumanB = {
type: "B";
name: string;
};
type HumanC = {
type: "C";
name: string;
location: string;
};
type Human = HumanA | HumanB | HumanC;
function getRandomHuman(): Human {
const types: Human[] = [
{ type: "A", name: "Alice", age: 30 },
{ type: "B", name: "Bob" },
{ type: "C", name: "Charlie", location: "New York" },
];
return types[Math.floor(Math.random() * types.length)]!;
}
const greetingMessage = match(getRandomHuman())
.with(
{ type: "A", name: P.select() },
// 引数なしのP.select()だと第1引数にマッチした値、第2引数にマッチしたオブジェクト全体が入る
(name, human) => `Hello ${name}, you are ${human.age} years old!`,
)
.with(
{ type: "B", name: P.select() },
// 第2引数を使わない場合は省略可能
(name) => `Hi ${name}, welcome!`,
)
.with(
{ type: "C", name: P.select("name"), location: P.select("location") },
// 複数必要な場合はP.select(名前)が必要. 第1引数にマッチした値がオブジェクトとして入る
({ name, location }) => `Hey ${name} from ${location}!`,
)
.exhaustive();
```
このケースなら [[P.select (ts-pattern)|P.select]] を使わない方が字数を少なくてシンプルに書けるが、対象オブジェクトのネストが深い場合は恩恵が出てくる。