【发布时间】:2019-06-19 01:32:31
【问题描述】:
在流程中,我可以像这样定义一个动态文字类型:
const myVar = 'foo'
type X = {
[typeof myVar]: string
}
const myX: X = { foo: 1 } // will throw, because number
const myX: X = { foo: 'bar' } // will not throw
我现在正在尝试将一些代码转换为打字稿,但这种语法是不可能的。但是,我无法弄清楚如何在打字稿中做到这一点。这是我正在使用的代码(已经部分翻译成打字稿):
type Theme = {
fontSizes: number[]
}
type SystemObj = {
prop: string,
cssProperty?: string,
}
type Props<T> = T & {
theme: Theme,
}
const style = <X>({
prop,
cssProperty,
}: SystemObj) => {
const cssProp = cssProperty || prop
return (props: Props<{
[typeof cssProp]: X
}>) => {
return props
}
}
const fontSize = style<number>({
prop: 'fontSize',
})
fontSize({
fontSize: 2,
theme: {
fontSizes: [12, 14, 16],
}
})
当前抛出(在打字稿游乐场上打开所有选项)
Argument of type '{ fontSize: number; theme: { fontSizes: number[]; }; }' is not assignable to parameter of type '{ theme: Theme; }'.
Object literal may only specify known properties, and 'fontSize' does not exist in type '{ theme: Theme; }'.
编辑:
所以我让它工作,正是我希望它工作的方式:
type Theme = {
fontSizes: number[]
}
type SystemObj = {
prop: string,
cssProperty?: string,
}
type Props = {
theme: Theme,
}
const style = <X extends string, Y>({
prop,
cssProperty,
}: SystemObj) => {
const cssProp = cssProperty || prop
return (props: Props & { [K in X]: Y }) => {
return props
}
}
const fontSize = style<'fontSize', number>({
prop: 'fontSize',
})
fontSize({
fontSize: 123,
theme: {
fontSizes: [12, 14, 16],
}
})
这里是否可以去掉<'fontSize' 部分?:
const fontSize = style<'fontSize', number>({
prop: 'fontSize',
})
然后输入这个
const fontSize = style<number>({
prop: 'fontSize',
})
它完全按照我希望的方式工作,只是想知道我是否可以在此处删除重复项(因为 prop: 'fontSize' 已经定义了密钥)。这又回到了我最初的问题,我如何将值 fontSize 定义为我的类型中的键。
【问题讨论】:
-
不完全确定您的问题是什么。你也可以在 TypeScript 中使用相同的方法。您唯一需要更改的是将
[typeof myVar]替换为[myVar]。我不太了解 Flow,但我怀疑您是否真的必须使用[typeof myVar]来获取myVar的 content,因为typeof myVar将评估为“字符串”,而不是“foo” . -
嗯,就是这样,我确实希望字符串的 content 成为这里的关键。这样这部分:`return (props: Props) => { return props}`returns 的类型为
{ theme: Theme, fontSize: number } -
我让它完全按照我现在想要的方式工作@str,但是请参阅上面的编辑,我想知道我是否可以删除
const style = <'fontSize'部分,因为我传递给函数的对象定义已经有钥匙了。 -
@MartinBroder 我认为这是不可能的 atm 因为 TS 不允许泛型类型的部分显式定义:github.com/Microsoft/TypeScript/issues/10571 但您至少可以确保属性值和泛型文字是等效: type SystemObj
= { prop: X, cssProperty?: string, } const style = ({ prop, cssProperty, }: SystemObj ) => { const cssProp = cssProperty | | prop return (props: Props & { [K in X]: Y }) => { return props } } -
您能否详细说明
SystemObj的用途并展示实际用例?您只需:const style = <T>() => (props: Props & T) => props; const fontSize = style<{fontSize: number}>();即可达到相同的效果(如在编辑示例中)
标签: javascript reactjs typescript types flowtype