diff --git a/packages/core/types/src/common/__tests__/pluralize.spec.ts b/packages/core/types/src/common/__tests__/pluralize.spec.ts new file mode 100644 index 0000000000000..50761c155ed40 --- /dev/null +++ b/packages/core/types/src/common/__tests__/pluralize.spec.ts @@ -0,0 +1,44 @@ +import { expectTypeOf } from "expect-type" +import { Pluralize } from "../common" + +describe("Pluralize", () => { + test("pluralize uncountable nouns", () => { + expectTypeOf>().toEqualTypeOf<"media">() + expectTypeOf>().toEqualTypeOf<"Media">() + expectTypeOf>().toEqualTypeOf<"you">() + expectTypeOf>().toEqualTypeOf<"sheep">() + expectTypeOf>().toEqualTypeOf<"series">() + expectTypeOf>().toEqualTypeOf<"species">() + expectTypeOf>().toEqualTypeOf<"deer">() + }) + + test("pluralize words ending with fe", () => { + expectTypeOf>().toEqualTypeOf<"wives">() + expectTypeOf>().toEqualTypeOf<"knives">() + }) + + test("pluralize words ending with o", () => { + expectTypeOf>().toEqualTypeOf<"heroes">() + }) + + test("pluralize words ending with ch", () => { + expectTypeOf>().toEqualTypeOf<"watches">() + }) + + test("pluralize words ending with z", () => { + expectTypeOf>().toEqualTypeOf<"fizes">() + }) + + test("pluralize words ending with y", () => { + expectTypeOf>().toEqualTypeOf<"puppies">() + }) + + test("pluralize words with special rules", () => { + expectTypeOf>().toEqualTypeOf<"people">() + expectTypeOf>().toEqualTypeOf<"children">() + expectTypeOf>().toEqualTypeOf<"men">() + expectTypeOf>().toEqualTypeOf<"criteria">() + expectTypeOf>().toEqualTypeOf<"teeth">() + expectTypeOf>().toEqualTypeOf<"feet">() + }) +}) diff --git a/packages/core/types/src/common/common.ts b/packages/core/types/src/common/common.ts index a30cfbd8164f1..af394480ea8bb 100644 --- a/packages/core/types/src/common/common.ts +++ b/packages/core/types/src/common/common.ts @@ -240,39 +240,153 @@ export interface NumericalComparisonOperator { lte?: number } +/** + * The keywords that does not have a plural form + */ +type UncountableRules = + | "adulthood" + | "advice" + | "agenda" + | "aid" + | "aircraft" + | "alcohol" + | "ammo" + | "analytics" + | "anime" + | "athletics" + | "audio" + | "bison" + | "blood" + | "bream" + | "buffalo" + | "butter" + | "carp" + | "cash" + | "chassis" + | "chess" + | "clothing" + | "cod" + | "commerce" + | "cooperation" + | "corps" + | "debris" + | "diabetes" + | "digestion" + | "elk" + | "energy" + | "equipment" + | "excretion" + | "expertise" + | "firmware" + | "flounder" + | "fun" + | "gallows" + | "garbage" + | "graffiti" + | "hardware" + | "headquarters" + | "health" + | "herpes" + | "highjinks" + | "homework" + | "housework" + | "information" + | "jeans" + | "justice" + | "kudos" + | "labour" + | "literature" + | "machinery" + | "mackerel" + | "mail" + | "media" + | "mews" + | "moose" + | "music" + | "mud" + | "manga" + | "news" + | "only" + | "personnel" + | "pike" + | "plankton" + | "pliers" + | "police" + | "pollution" + | "premises" + | "rain" + | "research" + | "rice" + | "salmon" + | "scissors" + | "series" + | "sewage" + | "shambles" + | "shrimp" + | "software" + | "staff" + | "swine" + | "tennis" + | "traffic" + | "transportation" + | "trout" + | "tuna" + | "wealth" + | "welfare" + | "whiting" + | "wildebeest" + | "wildlife" + | "you" + | "deer" + | "sheep" + +type PluralizationSpecialRules = { + person: "people" + child: "children" + man: "men" + criterion: "criteria" + tooth: "teeth" + foot: "feet" +} + /** * @ignore */ -export type Pluralize = Singular extends `${infer R}ss` - ? `${Singular}es` - : Singular extends `${infer R}sis` - ? `${R}ses` - : Singular extends `${infer R}is` - ? `${R}ises` - : Singular extends `${infer R}s` - ? `${Singular}` - : Singular extends `${infer R}ey` - ? `${R}eys` - : Singular extends `${infer R}y` - ? `${R}ies` - : Singular extends `${infer R}es` - ? `${Singular}` - : Singular extends - | `${infer R}sh` - | `${infer R}ch` - | `${infer R}x` - | `${infer R}z` - | `${infer R}o` - ? `${Singular}es` - : Singular extends `${infer R}fe` - ? `${R}ves` - : Singular extends `${infer R}ex` | `${infer R}ix` - ? `${R}ices` - : Singular extends `${infer R}eau` - ? `${R}eaux` - : Singular extends `${infer R}ieu` - ? `${R}ieux` - : `${Singular}s` +export type Pluralize = + Lowercase extends keyof PluralizationSpecialRules + ? PluralizationSpecialRules[Lowercase] + : Lowercase extends UncountableRules + ? Singular + : Singular extends `${infer R}ss` + ? `${Singular}es` + : Singular extends `${infer R}sis` + ? `${R}ses` + : Singular extends `${infer R}is` + ? `${R}ises` + : Singular extends `${infer R}s` + ? `${Singular}` + : Singular extends `${infer R}ey` + ? `${R}eys` + : Singular extends `${infer R}y` + ? `${R}ies` + : Singular extends `${infer R}es` + ? `${Singular}` + : Singular extends + | `${infer R}sh` + | `${infer R}ch` + | `${infer R}x` + | `${infer R}z` + | `${infer R}o` + ? `${Singular}es` + : Singular extends `${infer R}fe` + ? `${R}ves` + : Singular extends `${infer R}ex` | `${infer R}ix` + ? `${R}ices` + : Singular extends `${infer R}eau` + ? `${R}eaux` + : Singular extends `${infer R}ieu` + ? `${R}ieux` + : `${Singular}s` export type SnakeCase = S extends `${infer T}${infer U}${infer V}`