scalar.dictionary.ts

scalar dictionary는 scalar에 언어별 레이블을 붙입니다. scalar 이름, 각 필드, 각 enum 값이 대상입니다. scalar의 constant에 필드나 enum 값을 추가할 때마다 이 파일도 함께 엽니다.
이 페이지에서 쓰는 말
레이블
사람이 읽는 이름으로, t(["Amount", "금액"])처럼 언어마다 하나씩 적습니다.
.desc()
레이블 뒤에 이어 붙이는 한 문장짜리 설명입니다.
언어 배열
scalarDictionary(["en", "ko"])에 적은 언어 순서대로 문자열을 하나씩 담은 배열입니다.
key
코드가 레이블을 꺼낼 때 쓰는 점 경로로, price.amount 같은 모양입니다.
module dictionary보다 작은 builder
scalar는 model 안에 들어가는 값이라, 레이블을 붙일 자기만의 목록이나 API가 없습니다. 그래서 scalarDictionary에는 query, sort, slice, endpoint 단계가 아예 없습니다.
단계
model
scalar
service
scalar가 붙이는 레이블
.of()
✓
✓
scalar나 model 자체의 이름입니다.
.model()
✓
✓
constant의 필드마다 레이블 하나입니다.
.enum()
✓
✓
enumOf()로 만든 enum의 값마다 레이블 하나입니다.
모든 종류에 있는 메시지
.error()
✓
✓
✓
new Err()로 던지는 에러 문구입니다.
.translate()
✓
✓
✓
그 밖의 짧은 문구입니다.
저장된 목록이나 API가 있을 때만
.insight()
✓
개수 같은 목록의 요약 수치입니다.
.query() · .sort()
✓
목록의 필터와 정렬 방식입니다.
.slice()
✓
클라이언트 store가 불러오는 데이터 뷰입니다.
.endpoint()
✓
✓
signal endpoint와 그 인자입니다.
✓이 단계가 있음이 단계가 없음
  • builder는 모듈 종류에 맞춰 고릅니다. lib/<model>에는 modelDictionary, lib/__scalar/<scalar>에는 scalarDictionary, lib/_<service>에는 serviceDictionary를 씁니다.

기본 패턴

scalarDictionary(["en", "ko"])로 시작해 레이블 종류마다 단계를 하나씩 이어 붙입니다. enum 하나와 추가 문구 하나가 있는 scalar는 이렇게 생겼습니다.
apps/myapp/lib/__scalar/price/price.dictionary.ts
  • dictionary라는 이름의 const 하나를 export합니다. workspace의 model, scalar, service dictionary가 모두 이 이름을 씁니다.
  • constant는 import type으로 가져옵니다. dictionary는 constant를 타입 인자로만 쓰므로 타입만 가져오면 충분합니다.
  • 레이블과 같은 말이 되더라도 모든 레이블에 .desc()를 붙입니다. 영어 레이블은 Title Case로, 한국어 레이블은 평소 쓰는 도메인 용어로 씁니다.
  • enum도 추가 문구도 없다면 .model()에서 끝냅니다. libs/shared/lib/__scalar/restrictInfo/restrictInfo.dictionary.ts는 .of()와 .model()만으로 이루어져 있습니다.

Builder 순서

단계는 이 순서로 쓰고, 담을 것이 없는 단계는 건너뜁니다. 각 단계는 컴포넌트가 l()로 읽는 key 묶음을 하나씩 채웁니다.
.of()
scalar 자체의 이름과 설명입니다.
.model<Price>()
constant의 모든 필드이며, 하나라도 빠지면 타입 에러입니다.
.enum<Currency>("currency")
enum 하나의 모든 값이며, key는 enum 자신의 이름 아래에 생깁니다.
.error({})
new Err()로 던지는 에러 문구로, scalar에서는 드물게 씁니다.
.translate({})
scalar에 속한 그 밖의 짧은 문구입니다.
  • 순서는 관례이지 검사 대상이 아닙니다. 모든 단계가 같은 builder를 돌려주므로 어떤 순서든 컴파일됩니다. 읽는 사람이 기대하는 자리에서 각 단계를 찾도록 이 순서를 지킵니다.
  • enum 레이블은 enum 이름 아래에 있습니다. l("price.currency.KRW")가 아니라 l("currency.KRW")로 읽습니다. 앞의 것은 없는 key라 타입 에러가 납니다.
  • 직접 코드를 쓰지 않아도 보이는 레이블이 있습니다. 모델 탐색기 Constant.Doc은 .of()의 설명과 각 필드의 .desc()를 보여 줍니다.

언어 순서

scalarDictionary()에 넘긴 배열이 파일 안 모든 언어 배열의 순서를 정합니다. ["en", "ko"]로 시작했다면 모든 곳에서 영어를 먼저, 한국어를 두 번째로 씁니다.
apps/myapp/lib/__scalar/price/price.dictionary.ts
배열의 자리마다 언어가 하나씩 정해져 있습니다.
"en"
모든 배열의 첫 번째 자리입니다: "Price", "Price value".
"ko"
모든 배열의 두 번째 자리입니다: "가격", "가격 값".
  • 이 workspace의 dictionary는 모두 ["en", "ko"]를 씁니다. model, scalar, service dictionary 모두 영어가 먼저입니다.
  • 순서가 뒤바뀐 배열은 에러가 나지 않습니다. 둘 다 문자열이라 ["가격", "Price"]도 컴파일되고, 영어 페이지에 한국어가 나옵니다.
  • 배열에 없는 언어는 기본 언어로 대신합니다. 배열에 없는 locale은 앱의 기본 locale 문구를, 그것도 없으면 key 문자열을 보여 줍니다. 인자 없이 부른 scalarDictionary()는 영어 하나뿐입니다.

Enum 이름 맞추기

constant가 enumOf()로 선언한 enum은 .enum()에서 레이블을 받고, 두 호출의 이름은 정확히 같아야 합니다. 아래 constant는 currency를 선언하고 필드에 씁니다.
apps/myapp/lib/__scalar/price/price.constant.ts
dictionary는 같은 이름으로 레이블을 붙이고, enum class를 타입 인자로 넘깁니다.
apps/myapp/lib/__scalar/price/price.dictionary.ts
이름 하나, 쓰이는 곳 넷
enumOf("currency", …)
price.constant.ts에서 enum과 그 이름을 선언합니다.
.enum<Currency>("currency", …)
price.dictionary.ts에서 같은 이름 아래 모든 값에 레이블을 붙입니다.
l("currency.KRW")
컴포넌트에서 값 하나의 레이블을 읽습니다.
items={cnst.Currency}
Field.ToggleSelect는 같은 key로 버튼 이름을 붙이므로 따로 쓸 코드가 없습니다.
  • enum 하나에 .enum() 호출 하나입니다. apps/akan/lib/__scalar/docPage/docPage.dictionary.ts는 docSection과 docPriority를 위해 두 번 이어 붙입니다.

짧은 전용 문구

.translate()에는 scalar 자체에 속한 짧은 문구만 둡니다. 페이지나 동작에 속한 문구는 상위 module의 dictionary에 둡니다. 문구마다 key와 언어 배열을 하나씩 적습니다.
apps/myapp/lib/__scalar/price/price.dictionary.ts
컴포넌트는 필드 레이블과 똑같이 scalar 이름으로 이 문구를 읽습니다.
apps/myapp/ui/PriceLabel.tsx
  • key는 필드 레이블과 같은 자리에 놓입니다. free는 price.amount와 같은 방식으로 price.free로 읽습니다.
  • 어느 필드도 쓰지 않는 key를 고릅니다. .translate({ amount: … })는 amount 필드 레이블을 덮어씁니다. 둘 다 price.amount이기 때문입니다.
  • 레이블을 읽는다고 클라이언트 경계가 생기지 않습니다. usePage()는 서버 컴포넌트에서도 동작하므로 PriceLabel에 "use client"가 필요 없습니다.

MIT 라이선스 하에 배포되었습니다.

내 AI에 이 문서 연결하기

MCPhttps://akanjs.com/mcp
Copyright © 2026 Akan.js 모든 권리 보유.시스템 관리자bassman