【问题标题】:Generic tree with UNIQUE generic nodes具有唯一通用节点的通用树
【发布时间】:2022-01-08 00:32:27
【问题描述】:

问题描述

我有一个带有通用节点的通用树。您可以将其视为具有多级子元素的扩展路由器配置。

关键是,每个节点都可以有其他泛型类型,而不是它的父节点(更多细节 - Typescript Playground)。

所以当节点有子节点时,问题在于键入它的节点泛型。

代码

type ReactNode = string



type languageTag = 'en' | 'ru'/* | 'de' | 'cs' | 'fr' | 'cn' | 'pl' */



// the type below may be the problem
type translations<T extends unknown = unknown> = {
  [key in languageTag]: T
}



interface pageData<T extends unknown = unknown> {
  path: string,
  contentTranslations: translations<T>
  element: ReactNode,
  children?: Array<pageData<T>>
}



const informationPageData: pageData<{ hobbies: string/* , fullName: string, birthDate: string, sex: string, ... */ }> = {
  path: 'information',
  contentTranslations: {
    en: { hobbies: 'hobbies' },
    ru: { hobbies: 'хобби' }
  },
  element: 'profile information'
}



const profilePageData: pageData<{ recentPosts: string }> = {
  path: ':profileId',
  contentTranslations: {
    en: { recentPosts: 'recent posts' },
    ru: { recentPosts: 'недавние посты' }
  },
  element: 'profile component',
  children: [ informationPageData ] // Error
}



const profilesPageData: pageData<{ youMayKnow: string }> = {
  path: '/profiles',
  contentTranslations: {
    en: { youMayKnow: 'you may know' },
    ru: { youMayKnow: 'возможно вы знакомы' }
  },
  element: 'profiles list',
  children: [ profilePageData ] // Error
}

问题

我应该从哪里获得这些类型?

我们的目标是让它尽可能干燥。也许通过类型推断?

Typescript Playground

我可以请你帮忙吗?

【问题讨论】:

  • @KenWhite 已编辑。

标签: reactjs typescript translation type-inference


【解决方案1】:

pageData 接口的问题是父级T 与子级所需的类型相同。您想要的是打开泛型类型以容纳任何记录,从而允许子项定义自己的属性。

interface pageData<T extends Record<string, string>> {
  path: string,
  contentTranslations: translations<T>
  element: ReactNode,
  children?: Array<pageData<Record<string, string>>>
}

你仍然会得到组件 props 的强类型特性,但没有继承的限制

【讨论】:

  • 是否有可能以某种方式推断出子泛型类型?例如,如果我想递归遍历所有 pageData 对象并获取它们的 contentTranslations 类型?
  • @RamoFX 不,这会破坏泛型的目的。您必须对所有类型进行硬编码,然后在运行时键入断言,例如 const isHobby = (translation: any): translation is { hobby: string } =&gt; typeof translation.hobby === 'string')
  • 非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多