Skip to content

Commit

Permalink
feat(typegen): Intersect type when rules overlap instead of extending.
Browse files Browse the repository at this point in the history
  • Loading branch information
fdrault committed Aug 6, 2024
1 parent a3525fb commit 6b80950
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/translation/generate-template-data.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ describe("generateType", () => {
expect(result[0]).toMatchObject({
key: "day",
interpolations: [
{ name: "count", type: [{ value: "number" }, { value: "string" }] },
{ name: "count", type: [{ value: "number" }] },
{ name: "mood", type: [{ value: "string" }] },
{ name: "moods", type: [{ value: "string" }] },
],
Expand Down
19 changes: 14 additions & 5 deletions src/translation/generate-template-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
InterpolationTypeTemplateData,
TranslationEntryTemplateData,
} from "../templates/template-type";
import { intersection } from "./set";

type TranslationKey = string;
type Translation = string;
Expand Down Expand Up @@ -51,8 +52,8 @@ function toTemplateData(entries: TranslationEntry[]): TranslationEntryTemplateDa
const existingInterpolation = interpolations.find((interpol) => interpol.name === name);

if (existingInterpolation) {
// Merge types if the interpolation already exists
existingInterpolation.type = mergeUniqueTypes(existingInterpolation.type, types);
// Intersect types if the interpolation already exists to provide the stricter type
existingInterpolation.type = intersectTypes(existingInterpolation.type, types);
} else {
// Add new interpolation
interpolations.push({
Expand Down Expand Up @@ -85,12 +86,20 @@ function toTemplateData(entries: TranslationEntry[]): TranslationEntryTemplateDa
return Array.from(entryMap.values());
}

function mergeUniqueTypes(
function intersectTypes(
existingTypes: InterpolationTypeTemplateData[],
newTypes: string[]
): InterpolationTypeTemplateData[] {
const existingTypeValues = new Set([...existingTypes.map((t) => t.value), ...newTypes]);
return Array.from(existingTypeValues).map((it) => ({ value: it }));
const current = new Set(...existingTypes.map((t) => t.value));
const other = new Set(newTypes);

const intersect = intersection(current, other);
if (intersect.size > 0) {
return Array.from(intersect).map((it) => ({ value: it }));
} else {
// if not types are in common, the type is defined by the first encountered rule.
return existingTypes;
}
}

function processTranslation(
Expand Down
19 changes: 19 additions & 0 deletions src/translation/set.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export function intersection<T>(current: Set<T>, other: Set<T>) {
const result = new Set<T>();

if (current.size > other.size) {
for (const it of current) {
if (other.has(it)) {
result.add(it);
}
}
} else {
for (const it of other) {
if (current.has(it)) {
result.add(it);
}
}
}

return result;
}

0 comments on commit 6b80950

Please sign in to comment.