Как я могу динамически расширить функциональность строк / объектов в TypeScript? - PullRequest
1 голос
/ 12 апреля 2020

Я работаю над некоторым модулем локализации, для этого я включил модули TypesScript Json, в настоящее время я пытаюсь добиться следующего использования:

base. json:

{
  "base": "",
  "greeting": "{{name}}",
  "extras": {
    "array": ["{{city}}", 0]
  }
}

ru. json / nl. json

{
  "base": "hello",
  "greeting": "hello {{name}}",
  "extras": {
    "array": ["I live in {{city}}", 7]
  }
}

Я хочу, чтобы все файлы реализовали базу, поэтому я сделал следующее

import base from "./locale/base.json";
import en from "./locale/en.json";
import nl from "./locale/nl.json";

type Language = keyof typeof availableLanguages;

const availableLanguages: Record<"en" | "nl", typeof base> = {
  en,
  nl,
} as const;

export const setLanguage = <T extends Language>(lang: T) => {
  return availableLanguages[lang];
};

Это минимальный минимум Я приступил к работе, однако я хочу получить это использование:

const t = setLanguage("en")
t.base // hello
t.greeting({ name: "Daniell" }) // hello Daniell
t.extras.array({ city: "My city" }) // ["I live in My city", 7]

Мне было интересно, как я могу добиться чего-то подобного, я мог бы использовать некоторую помощь, в частности:

  • Если бы я должен был генерировать наборы из моей базы. json, извлекая нотации усов в свой собственный интерфейс, как мне их структурировать, чтобы сопоставить их с каждым путем, и будет ли это лучшим подходом?
  • Как я должен ввести интерфейс для строк / массивов? поскольку приведенный ниже пример не даст мне смысла
interface String {
  (...args: any): any;
}

1 Ответ

0 голосов
/ 12 апреля 2020

Хотя вы не можете получить имена ожидаемых интерполированных параметров, вы все равно можете получить правильную форму json (используя флаг --resolveJsonModule). Таким образом, что-то вроде

type RecursiveProxified<T> = {
  [K in keyof T]: T[K] extends string
    ? (...values) => string
    : T[K] extends Array<string | number>
    ? (...values) => Array<string | number>
    : T[K] extends {}
    ? RecursiveProxified<T[K]>
    : never
};

может обеспечить базовые c проверки типов и intelliSense.

const proxifyTranslations = <T>(translations: T): RecursiveProxified<T> => {
  // there should be actual implementation
  return translations as any; 
};

const availableLanguages = {
  en: json // json module
};

const setLanguage = (lang: keyof typeof availableLanguages) => {
  return proxifyTranslations(availableLanguages[lang]);
};

const t = setLanguage("en");

t.base(123); // string
t.extras.array(123); // Array<string | number>

Playground link

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...