是否可以声明动态接口?

时间:2019-11-14 15:13:24

标签: reactjs typescript

我目前正在将基于jss的样式解决方案转换为typescript,在以下情况下我迷路了。

考虑我的基本设置

import { useStyles } from './styles'

const styles = theme =>({
    root : { color: 'white' },
    foo : { backgroundColor: 'red' },
})

const Component = () =>{
    const classes = useStyles(styles)

    return <div className={classes.root} />
}

您将样式的对象传递给useStyles,返回的值是一个对象,其中包含在styles内部声明的所有键。所以我的classes对象看起来像这样

{
    root : 'random-name123',
    foo : 'random-name124'
}

由于我可能不知道styles拥有哪些键,所以我当前的classes接口只是一个字典

interface Classes {
    [index: string]: string
}

我的问题是:

我是否可以这样声明一个interface,以便将传递给styles的所有键都声明为Classes的一部分?这样,当我键入classes.时,我就能看到classes的所有可能的键吗?

换句话说,我希望组成Classes的键是可预测的。这样,如果我通过styles这样的对象

{
    foo : {/*...*/},
    bar: {/*...*/}
}

我的Classes界面看起来像

{
    foo : string,
    bar : string
}   

2 个答案:

答案 0 :(得分:3)

我希望这就是你的意思:

const styles = {
  root: 'value1',
  foo: 'value2'
};

type stylesType = typeof styles;

interface Classes extends stylesType {
  [x: string]: string;
}

现在,将对象键入为类时,它将具有键rootfoo

受到Types from both keys and values of object in Typescript

的启发

答案 1 :(得分:1)

在Typescript中,您可以使用Record实用程序类型将类型的并集映射到字典中的另一种类型。

要获取已定义对象的所有键,可以使用keyof typeof object,这将为您提供"root" | "foo"

因此,如果要将所有键映射到字符串,请使用:

type Classes = Record<keyof typeof styles, string>