fix: pluralize type helper to account for uncountable nouns and special rules (#10011)
This commit is contained in:
44
packages/core/types/src/common/__tests__/pluralize.spec.ts
Normal file
44
packages/core/types/src/common/__tests__/pluralize.spec.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { expectTypeOf } from "expect-type"
|
||||
import { Pluralize } from "../common"
|
||||
|
||||
describe("Pluralize", () => {
|
||||
test("pluralize uncountable nouns", () => {
|
||||
expectTypeOf<Pluralize<"media">>().toEqualTypeOf<"media">()
|
||||
expectTypeOf<Pluralize<"Media">>().toEqualTypeOf<"Media">()
|
||||
expectTypeOf<Pluralize<"you">>().toEqualTypeOf<"you">()
|
||||
expectTypeOf<Pluralize<"sheep">>().toEqualTypeOf<"sheep">()
|
||||
expectTypeOf<Pluralize<"series">>().toEqualTypeOf<"series">()
|
||||
expectTypeOf<Pluralize<"species">>().toEqualTypeOf<"species">()
|
||||
expectTypeOf<Pluralize<"deer">>().toEqualTypeOf<"deer">()
|
||||
})
|
||||
|
||||
test("pluralize words ending with fe", () => {
|
||||
expectTypeOf<Pluralize<"wife">>().toEqualTypeOf<"wives">()
|
||||
expectTypeOf<Pluralize<"knife">>().toEqualTypeOf<"knives">()
|
||||
})
|
||||
|
||||
test("pluralize words ending with o", () => {
|
||||
expectTypeOf<Pluralize<"hero">>().toEqualTypeOf<"heroes">()
|
||||
})
|
||||
|
||||
test("pluralize words ending with ch", () => {
|
||||
expectTypeOf<Pluralize<"watch">>().toEqualTypeOf<"watches">()
|
||||
})
|
||||
|
||||
test("pluralize words ending with z", () => {
|
||||
expectTypeOf<Pluralize<"fiz">>().toEqualTypeOf<"fizes">()
|
||||
})
|
||||
|
||||
test("pluralize words ending with y", () => {
|
||||
expectTypeOf<Pluralize<"puppy">>().toEqualTypeOf<"puppies">()
|
||||
})
|
||||
|
||||
test("pluralize words with special rules", () => {
|
||||
expectTypeOf<Pluralize<"person">>().toEqualTypeOf<"people">()
|
||||
expectTypeOf<Pluralize<"child">>().toEqualTypeOf<"children">()
|
||||
expectTypeOf<Pluralize<"man">>().toEqualTypeOf<"men">()
|
||||
expectTypeOf<Pluralize<"criterion">>().toEqualTypeOf<"criteria">()
|
||||
expectTypeOf<Pluralize<"tooth">>().toEqualTypeOf<"teeth">()
|
||||
expectTypeOf<Pluralize<"foot">>().toEqualTypeOf<"feet">()
|
||||
})
|
||||
})
|
||||
@@ -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 string> = 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<Singular extends string> =
|
||||
Lowercase<Singular> extends keyof PluralizationSpecialRules
|
||||
? PluralizationSpecialRules[Lowercase<Singular>]
|
||||
: Lowercase<Singular> 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 string> =
|
||||
S extends `${infer T}${infer U}${infer V}`
|
||||
|
||||
Reference in New Issue
Block a user