首页 > 解决方案 > 根据 Typescript 中的输入键从具有动态键的对象中选择值

问题描述

所以我的后端有一个这样的 JSON

name: "Hello",
nameTranslations: {nl:"Hallo", en: "Hello", fr: "Bonjour"}
description: "Hello",
descriptionTranslations: {nl:"Hallo", en: "Hello", fr: "Bonjour"}

我想构建一个函数,我将在其中放入对象和键,它会自动找到可能的最佳翻译。在 Javascript 中这很容易,但我想正确使用 Typescript,所以如果我忘记查询翻译,我就不会处理运行时错误(我使用 GraphQL)

function getText(object, key, language) {
  const best = object[`${key}Translations`][language];
  if (best) {
    return best;
  }

  return object[key];
}

我有一些打字稿要求

更新 基于@michmich112 的回答,我确实使用了以下功能

function translate<T extends BackendTranslations>(translations: T, fallback: string, language: keyof BackendTranslations) => {
      return translations[language] || fallback;
}

translate(project.nameTranslations, project.name)

我将保持答案开放,因为我仍然对这是否可以在 Typescript 中工作感兴趣

标签: typescripttemplate-literals

解决方案


首先,您需要为 JSON 创建一个接口:

interface ITranslationData {
  nl: string
  en: string
  fr: string
}

interface ITranslation {
  name: string
  nameTranslations: ITranslationData
  description: string
  descriptionTranslations: ITranslationData
}

一旦你有了,你可以在你的函数上使用类型,如下所示:

function getText(obj: ITranslation, 
  key: keyof ITranslation,
  language: keyof ITranslationData): string {
  const best = obj[key][language];
  if (best) {
    return best;
  }

  return obj[key];
}

这将要求您的密钥准确无误,这意味着您将无法进行const best = object[${key}Translations][language];

这也意味着您可以在一行中编写代码:

function getText(obj: ITranslation, 
  key: keyof ITranslation,
  language: keyof ITranslationData): string {
  return obj[key][language] || obj[key];
}

推荐阅读