๋ฉ”์ธ ์ฝ˜ํ…์ธ ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ
Sonamu๋Š” ๋‹ค๊ตญ์–ด ๋ฉ”์‹œ์ง€ ์ž‘์„ฑ์„ ๋•๋Š” ํ—ฌํผ ํ•จ์ˆ˜๋“ค์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

josa - ํ•œ๊ตญ์–ด ์กฐ์‚ฌ ์ฒ˜๋ฆฌ

josa() ํ•จ์ˆ˜๋Š” ์•ž ๋‹จ์–ด์˜ ๋ฐ›์นจ ์œ ๋ฌด์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ์กฐ์‚ฌ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค:
import { josa } from "sonamu/dict";

josa("์‚ฌ๋žŒ", "์€๋Š”")  // "์‚ฌ๋žŒ์€"
josa("๋‚˜", "์€๋Š”")    // "๋‚˜๋Š”"

josa("๋ฌผ", "์ด๊ฐ€")    // "๋ฌผ์ด"
josa("๋ฐ”๋‹ค", "์ด๊ฐ€")  // "๋ฐ”๋‹ค๊ฐ€"

josa("๋ฐฅ", "์„๋ฅผ")    // "๋ฐฅ์„"
josa("์ปคํ”ผ", "์„๋ฅผ")  // "์ปคํ”ผ๋ฅผ"

josa("๋นต", "๊ณผ์™€")    // "๋นต๊ณผ"
josa("์šฐ์œ ", "๊ณผ์™€")  // "์šฐ์œ ์™€"

josa("์ง‘", "์œผ๋กœ")    // "์ง‘์œผ๋กœ"
josa("ํ•™๊ต", "์œผ๋กœ")  // "ํ•™๊ต๋กœ"

์ง€์›ํ•˜๋Š” ์กฐ์‚ฌ

์กฐ์‚ฌ๋ฐ›์นจ ์žˆ์„ ๋•Œ๋ฐ›์นจ ์—†์„ ๋•Œ
์€๋Š”์€๋Š”
์ด๊ฐ€์ด๊ฐ€
์„๋ฅผ์„๋ฅผ
๊ณผ์™€๊ณผ์™€
์œผ๋กœ์œผ๋กœ๋กœ

๋”•์…”๋„ˆ๋ฆฌ์—์„œ ์‚ฌ์šฉ

// ko.ts
import { josa } from "sonamu/dict";

export default {
  "validation.required": (field: string) => `${josa(field, "์€๋Š”")} ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค`,
  "validation.duplicate": (field: string) => `์ด๋ฏธ ์‚ฌ์šฉ์ค‘์ธ ${josa(field, "์ด๊ฐ€")} ์žˆ์Šต๋‹ˆ๋‹ค`,
  "error.notFound": (name: string) => `${josa(name, "์„๋ฅผ")} ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค`,
} as const;

// ์‚ฌ์šฉ
SD("validation.required")("์ด๋ฉ”์ผ")  // "์ด๋ฉ”์ผ์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค"
SD("validation.required")("์ด๋ฆ„")    // "์ด๋ฆ„์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค"

plural - ๋ณต์ˆ˜ํ˜• ์ฒ˜๋ฆฌ

plural() ํ•จ์ˆ˜๋Š” ์ˆซ์ž์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํ…์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค:
import { plural } from "sonamu/dict";

plural(0, { zero: "์—†์Œ", one: "1๊ฐœ", other: "์—ฌ๋Ÿฌ ๊ฐœ" })  // "์—†์Œ"
plural(1, { zero: "์—†์Œ", one: "1๊ฐœ", other: "์—ฌ๋Ÿฌ ๊ฐœ" })  // "1๊ฐœ"
plural(5, { zero: "์—†์Œ", one: "1๊ฐœ", other: "์—ฌ๋Ÿฌ ๊ฐœ" })  // "์—ฌ๋Ÿฌ ๊ฐœ"

// other์— ํ•จ์ˆ˜ ์‚ฌ์šฉ
plural(5, { other: (n) => `${n}๊ฐœ` })  // "5๊ฐœ"

// zero๋‚˜ one์ด ์—†์œผ๋ฉด other๋กœ ํด๋ฐฑ
plural(0, { other: "๊ธฐ๋ณธ๊ฐ’" })  // "๊ธฐ๋ณธ๊ฐ’"
plural(1, { other: "๊ธฐ๋ณธ๊ฐ’" })  // "๊ธฐ๋ณธ๊ฐ’"

์˜ต์…˜

์˜ต์…˜์กฐ๊ฑด์„ค๋ช…
zeron === 00์ผ ๋•Œ ํ…์ŠคํŠธ
onen === 11์ผ ๋•Œ ํ…์ŠคํŠธ
other๊ทธ ์™ธ๊ธฐ๋ณธ ํ…์ŠคํŠธ (ํ•„์ˆ˜)

๋”•์…”๋„ˆ๋ฆฌ์—์„œ ์‚ฌ์šฉ

// ko.ts
import { plural } from "sonamu/dict";

export default {
  "items.count": (count: number) => plural(count, {
    zero: "ํ•ญ๋ชฉ์ด ์—†์Šต๋‹ˆ๋‹ค",
    one: "1๊ฐœ ํ•ญ๋ชฉ",
    other: (n) => `${n}๊ฐœ ํ•ญ๋ชฉ`,
  }),
  
  "cart.items": (count: number) => plural(count, {
    zero: "์žฅ๋ฐ”๊ตฌ๋‹ˆ๊ฐ€ ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค",
    other: (n) => `์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ${n}๊ฐœ ์ƒํ’ˆ`,
  }),
} as const;

createFormat - ์ˆซ์ž/๋‚ ์งœ ํฌ๋งท

createFormat() ํ•จ์ˆ˜๋Š” locale์— ๋งž๋Š” ์ˆซ์ž์™€ ๋‚ ์งœ ํฌ๋งทํ„ฐ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค:
import { createFormat } from "sonamu/dict";

const format = createFormat("ko");

format.number(1234567)  // "1,234,567"
format.date(new Date("2024-01-15"))  // "2024. 1. 15."

const enFormat = createFormat("en");
enFormat.number(1234567)  // "1,234,567"
enFormat.date(new Date("2024-01-15"))  // "1/15/2024"

๋”•์…”๋„ˆ๋ฆฌ์—์„œ ์‚ฌ์šฉ

// ko.ts
import { createFormat } from "sonamu/dict";

const format = createFormat("ko");

export default {
  "price.display": (price: number) => `${format.number(price)}์›`,
  "date.created": (date: Date) => `${format.date(date)} ๋“ฑ๋ก`,
  "validation.range": (field: string, min: number, max: number) =>
    `${field}์€(๋Š”) ${format.number(min)}~${format.number(max)} ์‚ฌ์ด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค`,
} as const;

์—ฌ๋Ÿฌ ํ—ฌํผ ์กฐํ•ฉ

๋ณต์žกํ•œ ๋ฉ”์‹œ์ง€๋Š” ์—ฌ๋Ÿฌ ํ—ฌํผ๋ฅผ ์กฐํ•ฉํ•ด์„œ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค:
// ko.ts
import { createFormat, josa, plural } from "sonamu/dict";

const format = createFormat("ko");

export default {
  // josa + plural
  "search.results": (keyword: string, count: number) =>
    `'${keyword}'${josa(keyword, "์œผ๋กœ")} ๊ฒ€์ƒ‰ํ•œ ๊ฒฐ๊ณผ ` +
    plural(count, {
      zero: "์—†์Œ",
      other: (n) => `${format.number(n)}๊ฑด`,
    }),
  
  // format + josa
  "order.total": (itemCount: number, total: number) =>
    `${itemCount}๊ฐœ ์ƒํ’ˆ, ์ด ${format.number(total)}์›`,
    
  // ๋ณตํ•ฉ ๋ฉ”์‹œ์ง€
  "dashboard.summary": (userName: string, taskCount: number, date: Date) =>
    `${userName}๋‹˜, ${format.date(date)} ๊ธฐ์ค€ ` +
    plural(taskCount, {
      zero: "์ฒ˜๋ฆฌํ•  ์ž‘์—…์ด ์—†์Šต๋‹ˆ๋‹ค",
      one: "1๊ฐœ์˜ ์ž‘์—…์ด ๋Œ€๊ธฐ ์ค‘์ž…๋‹ˆ๋‹ค",
      other: (n) => `${n}๊ฐœ์˜ ์ž‘์—…์ด ๋Œ€๊ธฐ ์ค‘์ž…๋‹ˆ๋‹ค`,
    }),
} as const;