@k8ordo/state

リンク

定義からリンクを作れるようになります。クエリは既定値を省いた形にそろい、パスはルート表で型検査できます。

このページの内容

hrefとsearch

ts
listState.href('/products');
// '/products'

listState.href('/products', { inStock: true, page: 2 });
// '/products?inStock=true&page=2'

listState.search({ page: 2 });
// 'page=2'

href(path, values?)は、定義からリンクを作ります。指定しなかったフィールドは既定値として扱い、既定値のままのフィールドはクエリから省きます。できるURLの形はURLを見てください。

search(values?)は、?を付けずにクエリ文字列だけを返します。パスを自分で組み立てるときに使います。たとえば、ダウンロードのURLに一覧と同じ条件を付けるときです。

返り値の型は、渡したパスをリテラルのまま残します。リンクを受け取る側の型検査(Next.jsの<Link>など)は、この型からクエリを除いてパスを確かめます。entryだけの定義では、hrefはクエリの無いリンクを返し、searchは空の文字列を返します。URLで表せない値を渡すと、どちらもhas no URL serializationを含むエラーになります。

Viteのbase

ts
listState.href('/products', { page: 2 });
// '/docs/products?page=2'

hrefに渡すパスは、ルート表のパターンと同じくbaseを含めずに書きます。返るリンクには、Viteのbaseが前に付きます。baseが'/docs/'なら、'/docs/products?page=2'になります。

@k8ordo/routerのhrefが返したリンクには、すでにbaseが付いているので渡さないでください。

Viteの外、たとえばNext.jsではimport.meta.envが無いので何も付けません。basePathは、そのフレームワークの<Link>が付けます。

パスの型検査

src/k8ordo.d.ts
import type { routes } from './routes';

declare module '@k8ordo/router' {
  interface Register {
    routes: typeof routes;
  }
}

declare module '@k8ordo/state' {
  interface Register {
    routes: typeof routes;
  }
}

Registerを一度拡張すると、アプリの中のすべてのhrefが、ルート表に無いパスを型エラーにします。routes: typeof routesの1行は、@k8ordo/routerのパスの型検査の拡張と同じです。@k8ordo/frameworkでは、この宣言がsrc/routes/から.k8ordo/register.gen.tsに生成されるので、自分では書きません。生成されるのは、アプリ自身のpackage.jsonのdependenciesかdevDependenciesに@k8ordo/stateがあるときです。ほかのパッケージを経由した依存は数えません。

パスは、表のパターンとセグメントごとに照合します。固定のセグメントは、パターンと同じ綴りが要ります。:paramのセグメントには、空でない1セグメントなら何でも入ります。テンプレートリテラルの${string}も通ります。*を含むパターンには、リンクできません。どのパターンにも当たらないパスは型エラーです。/:localeで始まる表でも、'/ja/nowhere'は拒まれます。

検査は@k8ordo/routerのNavigablePathを型として使うだけです。ルーターは任意のpeerのままで、実行時には読み込まれません。

types/k8ordo.d.ts
import type { Route } from 'next';

declare module '@k8ordo/state' {
  interface Register {
    path: Route;
  }
}

@k8ordo/router以外のルーターには渡せる表が無いので、そのルーターのパスのunionをpathに登録します。Next.jsならnextのRouteです。routesとpathの両方があれば、routesが優先されます。どちらも無ければ、/で始まる文字列が何でも通ります。

警告

落とし穴

Registerの拡張はアプリの中でだけ行ってください。共有のライブラリで拡張すると、その制約が使う側のすべてに及びます。

k8ordo

Baselineに入った機能を、制限なく使うReactのライブラリ群。

© 2026 k8o — MIT License

組版:Noto Sans JP / M PLUS 2