(ts) correct types for PronounsData

This commit is contained in:
Valentyne Stigloher 2024-06-06 15:19:33 +02:00
parent 4d40362a1e
commit ec0fb95be0
40 changed files with 131 additions and 136 deletions

View File

@ -0,0 +1 @@
export default [] as const;

View File

@ -4,4 +4,4 @@ export default [
'possessive_determiner', 'possessive_determiner',
'possessive_pronoun', 'possessive_pronoun',
'reflexive', 'reflexive',
]; ] as const;

View File

@ -11,4 +11,4 @@ export default [
'future', 'future',
'order', 'order',
'noun_end', 'noun_end',
]; ] as const;

28
locale/data.ts Normal file
View File

@ -0,0 +1,28 @@
export type PronounData<M extends string> = {
key: string;
description: string;
normative: boolean;
plural: boolean;
pluralHonorific: boolean;
pronounceable: boolean;
history?: string;
thirdForm?: M;
smallForm?: M;
sourcesInfo?: string;
hidden?: boolean;
} & { [morpheme in M]: string | null };
export interface PronounExamplesData {
singular: string;
plural?: string;
isHonorific?: boolean;
}
export interface NounTemplatesData {
masc: string;
fem: string;
neutr: string;
mascPl: string;
femPl: string;
neutrPl: string;
}

34
locale/dataFiles.ts Normal file
View File

@ -0,0 +1,34 @@
declare module '*/config.suml' {
import type { Config } from '~/locale/config.ts';
const config: Config;
export default config;
}
declare module '*/translations.suml' {
import type { Translations } from '~/locale/translations.ts';
const translations: Translations;
export default translations;
}
declare module '*/pronouns/pronouns.tsv' {
import type { PronounData } from '~/locale/data.ts';
const data: PronounData<string>[];
export default data;
}
declare module '*/pronouns/examples.tsv' {
import type { PronounExamplesData } from '~/locale/data.ts';
const data: PronounExamplesData[];
export default data;
}
declare module '*/nouns/nounTemplates.tsv' {
import type { NounTemplatesData } from '~/locale/data.ts';
const data: NounTemplatesData[];
export default data;
}
declare module '*.tsv' {
const data: Record<string, any>[];
export default data;
}

View File

@ -1,26 +0,0 @@
// sort Nominativ first and Dativ second to keep the convention that the first two morphemes identify the pronoun set
const cases = ['n', 'd', 'a', 'g'];
const morphemeByCase = (morphemeType) => {
return cases.map((caseAbbreviation) => `${morphemeType}_${caseAbbreviation}`);
};
const morphemeGroups = [
morphemeByCase('pronoun'),
morphemeByCase('possessive_determiner_f'),
morphemeByCase('possessive_determiner_m'),
morphemeByCase('possessive_determiner_n'),
morphemeByCase('possessive_determiner_x'),
morphemeByCase('possessive_determiner_pl'),
morphemeByCase('possessive_pronoun_f'),
morphemeByCase('possessive_pronoun_m'),
morphemeByCase('possessive_pronoun_n'),
morphemeByCase('possessive_pronoun_x'),
morphemeByCase('possessive_pronoun_pl'),
morphemeByCase('relative'),
morphemeByCase('demonstrative'),
['pronoun_equal', 'possessive_pronoun_substantivized'],
['adverb_because', 'adverb_back_then', 'adverb_by'],
['adjective_back_then'],
];
export default morphemeGroups.flatMap((morphemeGroup) => morphemeGroup);

View File

@ -0,0 +1,28 @@
// sort Nominativ first and Dativ second to keep the convention that the first two morphemes identify the pronoun set
const cases = ['n', 'd', 'a', 'g'] as const;
const morphemeByCase = <M extends string>(morphemeType: M): `${M}_${typeof cases[number]}`[] => {
return cases.map((caseAbbreviation) => `${morphemeType}_${caseAbbreviation}` as const);
};
export default [
...morphemeByCase('pronoun'),
...morphemeByCase('possessive_determiner_f'),
...morphemeByCase('possessive_determiner_m'),
...morphemeByCase('possessive_determiner_n'),
...morphemeByCase('possessive_determiner_x'),
...morphemeByCase('possessive_determiner_pl'),
...morphemeByCase('possessive_pronoun_f'),
...morphemeByCase('possessive_pronoun_m'),
...morphemeByCase('possessive_pronoun_n'),
...morphemeByCase('possessive_pronoun_x'),
...morphemeByCase('possessive_pronoun_pl'),
...morphemeByCase('relative'),
...morphemeByCase('demonstrative'),
'pronoun_equal',
'possessive_pronoun_substantivized',
'adverb_because',
'adverb_back_then',
'adverb_by',
'adjective_back_then',
] as const;

View File

@ -1,7 +0,0 @@
export default [
'pronoun_subject',
'pronoun_object',
'possessive_determiner',
'possessive_pronoun',
'reflexive',
];

View File

@ -4,4 +4,4 @@ export default [
'possessive_determiner', 'possessive_determiner',
'possessive_pronoun', 'possessive_pronoun',
'reflexive', 'reflexive',
]; ] as const;

View File

@ -1,3 +1,3 @@
export default [ export default [
'pronoun_subject', 'pronoun_subject',
]; ] as const;

View File

@ -9,4 +9,4 @@ export default [
'plural_direct_object_pronoun', 'plural_direct_object_pronoun',
'inflection', 'inflection',
'inflection_c', 'inflection_c',
]; ] as const;

View File

@ -6,4 +6,4 @@ export default [
'reflexive', 'reflexive',
'thirdForm', 'thirdForm',
'smallForm', 'smallForm',
]; ] as const;

View File

@ -7,4 +7,4 @@ export default [
'inflection_x', 'inflection_x',
'inflection_e', 'inflection_e',
'inflection_n', 'inflection_n',
]; ] as const;

View File

@ -10,4 +10,4 @@ export default [
'plural_indefinite_article', 'plural_indefinite_article',
'inflection_c', 'inflection_c',
'possessive', 'possessive',
]; ] as const;

View File

@ -4,4 +4,4 @@ export default [
'possessive_determiner', 'possessive_determiner',
'possessive_pronoun', 'possessive_pronoun',
'reflexive', 'reflexive',
]; ] as const;

View File

@ -10,4 +10,4 @@ export default [
'adjective', 'adjective',
'past_participle', 'past_participle',
'h', 'h',
]; ] as const;

View File

@ -1,3 +1,3 @@
export default [ export default [
'base_pronoun', 'base_pronoun',
]; ] as const;

View File

@ -1,3 +1,3 @@
export default [ export default [
'pronoun', 'pronoun',
]; ] as const;

View File

@ -9,4 +9,4 @@ export default [
'plural_direct_object_pronoun', 'plural_direct_object_pronoun',
'inflection', 'inflection',
'inflection_l', 'inflection_l',
]; ] as const;

View File

@ -4,4 +4,4 @@ export default [
'pronominal_poss', 'pronominal_poss',
'predicative_poss', 'predicative_poss',
'dative', 'dative',
]; ] as const;

View File

@ -3,4 +3,4 @@ export default [
'pronoun_object', 'pronoun_object',
'possessive', 'possessive',
'reflexive', 'reflexive',
]; ] as const;

View File

@ -27,4 +27,4 @@ export default [
'verb_go', 'verb_go',
'verb_o', 'verb_o',
'honorific', 'honorific',
]; ] as const;

View File

@ -15,4 +15,4 @@ export default [
'possessive', 'possessive',
'demonstrative_ss', 'demonstrative_ss',
'demonstrative_st', 'demonstrative_st',
]; ] as const;

View File

@ -4,4 +4,4 @@ export default [
'strengthening', 'strengthening',
'first_article', 'first_article',
'second_article', 'second_article',
]; ] as const;

View File

@ -13,4 +13,4 @@ export default [
'adjective', 'adjective',
'possessive', 'possessive',
'definitive', 'definitive',
]; ] as const;

View File

@ -2,4 +2,4 @@ export default [
'pronoun_nominative', 'pronoun_nominative',
'pronoun_object', 'pronoun_object',
'possessive', 'possessive',
]; ] as const;

View File

@ -1,3 +1,3 @@
export default [ export default [
'pronoun', 'pronoun',
]; ] as const;

View File

@ -1 +0,0 @@
export default [];

View File

@ -0,0 +1 @@
export default [] as const;

View File

@ -12,4 +12,4 @@ export default [
'adjective', 'adjective',
'possessive', 'possessive',
'definitive', 'definitive',
]; ] as const;

View File

@ -1,4 +1,4 @@
export default [ export default [
'3rd_person', '3rd_person',
'2nd_person', '2nd_person',
]; ] as const;

View File

@ -6,4 +6,4 @@ export default [
'article_n', 'article_n',
'article_d', 'article_d',
'article_a', 'article_a',
]; ] as const;

View File

@ -1,4 +1,4 @@
export default [ export default [
'3rd_person', '3rd_person',
'2nd_person', '2nd_person',
]; ] as const;

View File

@ -369,7 +369,7 @@ export class Locale {
text: "data:image/svg+xml," + encodeURIComponent(logoSource.text), text: "data:image/svg+xml," + encodeURIComponent(logoSource.text),
}; };
this._morphemes = (await this.importFile(["pronouns/morphemes.js"])) this._morphemes = (await this.importFile(["pronouns/morphemes.ts"]))
.default as string[]; .default as string[];
this._pronouns = []; this._pronouns = [];
this._pronounsByAlias = {}; this._pronounsByAlias = {};

64
plugins/data.d.ts vendored
View File

@ -1,64 +0,0 @@
import type { Config } from '../locale/config.ts';
import type { Translations } from '../locale/translations.ts';
export interface PronounsData<M extends string[]> {
key: string;
description: string;
normative: string;
[morpheme: M]: string | null;
plural: string;
pluralHonorific: string;
pronounceable: string;
history?: string;
thirdForm?: M;
smallForm?: M;
sourcesInfo?: string;
hidden?: boolean;
}
export interface PronounExamplesData {
singular: string;
plural?: string;
isHonorific?: boolean;
}
export interface NounTemplatesData {
masc: string;
fem: string;
neutr: string;
mascPl: string;
femPl: string;
neutrPl: string;
}
declare namespace Data {
declare module '*/config.suml' {
declare const config: Config;
export default config;
}
declare module '*/translations.suml' {
declare const translations: Translations;
export default translations;
}
declare module '*/pronouns/pronouns.tsv' {
declare const data: PronounsData[];
export default data;
}
declare module '*/pronouns/examples.tsv' {
declare const data: PronounExamplesData[];
export default data;
}
declare module '*/nouns/nounTemplates.tsv' {
declare const data: NounTemplatesData[];
export default data;
}
declare module '*.tsv' {
declare const data: Record<string, any>[];
export default data;
}
}

View File

@ -280,7 +280,7 @@ import Vue from 'vue';
import { examples, pronouns, pronounLibrary } from '../src/data.ts'; import { examples, pronouns, pronounLibrary } from '../src/data.ts';
import { ExampleCategory, ExamplePart, Pronoun } from '../src/classes.ts'; import { ExampleCategory, ExamplePart, Pronoun } from '../src/classes.ts';
import Compressor from '../src/compressor.js'; import Compressor from '../src/compressor.js';
import MORPHEMES from '../data/pronouns/morphemes.js'; import MORPHEMES from '../data/pronouns/morphemes.ts';
import { mapState } from 'vuex'; import { mapState } from 'vuex';
import Suggested from '../data/pronouns/Suggested.vue'; import Suggested from '../data/pronouns/Suggested.vue';
import type { PronounLibrary, Example } from '../src/classes.ts'; import type { PronounLibrary, Example } from '../src/classes.ts';

View File

@ -1,9 +1,10 @@
import { Pronoun } from './classes.ts'; import { Pronoun } from './classes.ts';
import Compressor from './compressor.js'; import Compressor from './compressor.js';
import { buildDict, isEmoji, unescapeControlSymbols } from './helpers.ts'; import { buildDict, isEmoji, unescapeControlSymbols } from './helpers.ts';
import MORPHEMES from '../data/pronouns/morphemes.js'; import MORPHEMES from '../data/pronouns/morphemes.ts';
import type { Config, NullPronounsConfig } from '../locale/config.ts'; import type { Config, NullPronounsConfig } from '../locale/config.ts';
import type { Translator } from './translator.js'; import type { Translator } from './translator.js';
import type { PronounData } from '../locale/data.ts';
export const addAliasesToPronouns = (pronouns: Record<string, Pronoun>): Record<string, Pronoun> => { export const addAliasesToPronouns = (pronouns: Record<string, Pronoun>): Record<string, Pronoun> => {
const pronounsWithAliases: Record<string, Pronoun> = {}; const pronounsWithAliases: Record<string, Pronoun> = {};
@ -274,7 +275,7 @@ export const buildPronoun = (
export const parsePronouns = ( export const parsePronouns = (
config: Config, config: Config,
pronounsRaw: Record<string, any>[], pronounsRaw: PronounData<string>[],
): Record<string, Pronoun> => { ): Record<string, Pronoun> => {
return buildDict(function* () { return buildDict(function* () {
for (const t of pronounsRaw) { for (const t of pronounsRaw) {

View File

@ -1,5 +1,5 @@
import { buildDict, buildList, capitalise, escapeControlSymbols, escapePronunciationString } from './helpers.ts'; import { buildDict, buildList, capitalise, escapeControlSymbols, escapePronunciationString } from './helpers.ts';
import MORPHEMES from '../data/pronouns/morphemes.js'; import MORPHEMES from '../data/pronouns/morphemes.ts';
import type { Translator } from './translator.js'; import type { Translator } from './translator.js';
import type { Config } from '../locale/config.ts'; import type { Config } from '../locale/config.ts';
@ -388,7 +388,7 @@ export class Pronoun {
pronounceable: boolean; pronounceable: boolean;
thirdForm: string | null; thirdForm: string | null;
smallForm: string | null; smallForm: string | null;
sourcesInfo: Record<keyof any, string> | null; sourcesInfo: string | null;
hidden: boolean; hidden: boolean;
static DESCRIPTION_MAXLENGTH = 64; static DESCRIPTION_MAXLENGTH = 64;
@ -405,7 +405,7 @@ export class Pronoun {
pronounceable: boolean = true, pronounceable: boolean = true,
thirdForm: string | null = null, thirdForm: string | null = null,
smallForm: string | null = null, smallForm: string | null = null,
sourcesInfo = null, sourcesInfo: string | null = null,
hidden: boolean = false, hidden: boolean = false,
) { ) {
this.config = config; this.config = config;
@ -437,7 +437,7 @@ export class Pronoun {
nameOptions(): string[] { nameOptions(): string[] {
const options: Set<string> = new Set(); const options: Set<string> = new Set();
const optionsN = (this.morphemes[MORPHEMES[0]] || '').split('&'); const optionsN = (this.morphemes[MORPHEMES[0]] || '').split('&');
if (MORPHEMES.length === 1) { if (MORPHEMES.length as number === 1) {
return optionsN; return optionsN;
} }
const optionsG: string[] = (this.morphemes[MORPHEMES[1]] || '').split('&'); const optionsG: string[] = (this.morphemes[MORPHEMES[1]] || '').split('&');

View File

@ -16,7 +16,7 @@ const translations = {
const translator = new Translator(translations, translations, []); const translator = new Translator(translations, translations, []);
// workaround to be independent of the current selected locale // workaround to be independent of the current selected locale
jest.unstable_mockModule('../data/pronouns/morphemes.js', () => { jest.unstable_mockModule('../data/pronouns/morphemes.ts', () => {
return { return {
default: ['pronoun_subject', 'pronoun_object', 'possessive_determiner', 'possessive_pronoun', 'reflexive'], default: ['pronoun_subject', 'pronoun_object', 'possessive_determiner', 'possessive_pronoun', 'reflexive'],
}; };

View File

@ -6,7 +6,7 @@ import { Example, gendersWithNumerus } from '../../src/classes.ts';
import type { ExpectationResult } from 'expect'; import type { ExpectationResult } from 'expect';
import { loadSumlFromBase } from '../../server/loader.ts'; import { loadSumlFromBase } from '../../server/loader.ts';
import type { Config } from '../../locale/config.ts'; import type { Config } from '../../locale/config.ts';
import type { NounTemplatesData, PronounExamplesData, PronounsData } from '../../plugins/data'; import type { NounTemplatesData, PronounExamplesData, PronounData } from '../../locale/data.ts';
const __dirname = new URL('.', import.meta.url).pathname; const __dirname = new URL('.', import.meta.url).pathname;
@ -44,8 +44,8 @@ describe.each(allLocales)('data files of $code', ({ code }) => {
const nounTemplates = loadTsv<NounTemplatesData>(`${__dirname}/../../locale/${code}/nouns/nounTemplates.tsv`); const nounTemplates = loadTsv<NounTemplatesData>(`${__dirname}/../../locale/${code}/nouns/nounTemplates.tsv`);
test('pronouns/pronouns.tsv match schema', async () => { test('pronouns/pronouns.tsv match schema', async () => {
const { default: MORPHEMES } = await import(`../../locale/${code}/pronouns/morphemes.js`); const { default: MORPHEMES } = await import(`../../locale/${code}/pronouns/morphemes.ts`);
const pronouns = loadTsv<PronounsData<string[]>>(`${__dirname}/../../locale/${code}/pronouns/pronouns.tsv`); const pronouns = loadTsv<PronounData<string>>(`${__dirname}/../../locale/${code}/pronouns/pronouns.tsv`);
if (pronouns.length === 0) { if (pronouns.length === 0) {
return; return;
} }
@ -80,7 +80,7 @@ describe.each(allLocales)('data files of $code', ({ code }) => {
expect(actual).toEqual(required); expect(actual).toEqual(required);
}); });
test('pronouns/examples.tsv contain valid morphemes', async () => { test('pronouns/examples.tsv contain valid morphemes', async () => {
const { default: MORPHEMES } = await import(`../../locale/${code}/pronouns/morphemes.js`); const { default: MORPHEMES } = await import(`../../locale/${code}/pronouns/morphemes.ts`);
for (const example of examples) { for (const example of examples) {
expect(example.singular).toHaveValidMorphemes(MORPHEMES); expect(example.singular).toHaveValidMorphemes(MORPHEMES);
if (example.plural) { if (example.plural) {