如何从Typescript中的值获取枚举键?

huangapple go评论48阅读模式
英文:

How do I get Enum key from a value in Typescript?

问题

我在一个大型项目中遇到了这个问题,所以我尝试简化我的问题到这个示例:

enum Screens {
    Home,
    About
}

interface HomeData {
    title: string
    posts: string[]
}

interface AboutData {
    title: string
}

interface PageData {
    [Screens.Home]: HomeData
    [Screens.About]: AboutData
}

const pageData: PageData = {
    [Screens.Home]: { title: 'Home', posts: ['intro', 'care'] },
    [Screens.About]: { title: 'Home' }
}

const addData = (screen: Screens, data: PageData[typeof screen]) => {
    pageData[screen] = data; //在这里出现错误,类型 'HomeData | AboutData' 不能赋值给类型 'HomeData & AboutData'。
}

我尝试动态传递数据对象给函数并将其分配给相应的屏幕,但 TypeScript 似乎无法理解 pageData[screen] 与函数的第一个参数 screen 相关联,它认为参数 data 必须满足 HomeData & AboutData

我知道可能有其他实现方式,但我的代码基础与这个结构紧密相关。

英文:

I'm having this problem in a large project, so I've tried to simplify my problem to this example:

enum Screens {
    Home,
    About
}

interface HomeData {
    title: string
    posts: string[]
}

interface AboutData {
    title: string
}

interface PageData {
    [Screens.Home]: HomeData
    [Screens.About]: AboutData
}

const pageData: PageData = {
    [Screens.Home]: { title: 'Home', posts: ['intro', 'care'] },
    [Screens.About]: { title: 'Home' }
}

const addData = (screen: Screens, data: PageData[typeof screen]) => {
    pageData[screen] = data; //error here, Type 'HomeData | AboutData' is not assignable to type 'HomeData & AboutData'.
}

Im trying to dynamically pass the data object to the function and assign it to the corresponding screen, but typescript dosen't seem to understand that pageData[screen] is tied to the first argument of the function: screen, it thinks that the argument data must satisfy HomeData & AboutData.

I know there are probably other ways to implement this, but my codebase is very intertwined to this structure.

答案1

得分: 2

你可以使用通用参数来获取特定“screen”的数据:

const addData = <T extends Screens>(screen: T, data: PageData[T]) => {
  pageData[screen] = data;
};

用法:

addData(Screens.Home, { posts: [], title: "" }); // 没有错误
addData(Screens.About, { posts: [], title: "" }); // 期望错误

playground

英文:

You can use the generic parameter for the screen and get the data of that specific screen:

const addData = &lt;T extends Screens&gt;(screen: T, data: PageData[T]) =&gt; {
  pageData[screen] = data;
};

Usage:

addData(Screens.Home, { posts: [], title: &quot;&quot; }); // no error
addData(Screens.About, { posts: [], title: &quot;&quot; }); // expected error

playground

huangapple
  • 本文由 发表于 2023年6月1日 05:54:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76377537.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定