我有一堆常量归类在对象中,但是我无法正确输入。我希望能够使用字符串或通过访问对象来传递对象属性。
我想要的是:
export const ACTIONS = {
SOMETHING: 'SOMETHING',
// ...
}
export function example(keyOrValue: SomeTypeDefThatWorks) {
// ...
}
example('SOMETHING') // valid
example(ACTIONS.SOMETHING) // valid
example('') // invalid
我到目前为止的尝试:
export const ACTIONS = {
SOMETHING: 'SOMETHING',
}
export type ActionsType = typeof ACTIONS
export type ActionValues = ActionsType[keyof ActionsType]
export function example1(keyOrValue: keyof ActionsType) {
// ...
}
example1('') // invalid
example1('SOMETHING') // valid
example1(ACTIONS.SOMETHING) // invalid
export function example2(keyOrValue: ActionsType[keyof ActionsType]) {
// ...
}
example2('') // valid but should not be
example2('SOMETHING') // valid
example2(ACTIONS.SOMETHING) // valid
export function example3(keyOrValue: keyof ActionsType | ActionsType[keyof ActionsType]) {
// ...
}
example3('') // valid but should not be
example3('SOMETHING') // valid
example3(ACTIONS.SOMETHING) // valid
// This one works, but is it possible to have this in an object?
export const SOMETHING = 'SOMETHING'
export function example4(keyOrValue: typeof SOMETHING) {
// ...
}
example4('') // invalid
example4('SOMETHING') // valid
example4(SOMETHING) // valid
有没有一种方法可以为对象的键或值定义类型?如果是这样,如何?
主要问题是编译器将ACTIONS
对象推断为{SOMETHING: string}
类型,并完全忘记了string literal type属性的SOMETHING
。然后,您的ActionValues
类型变为string
,并且您接受了所有不需要的string
值。编译器(合理地)不假定SOMETHING
属性的值将永远保持不变。是的,ACTIONS
itself是一个const
,因此您永远无法为ACTIONS
变量分配新值,但是它的属性仍然可变,并且编译器假定它可以使用任何string
]值。
[如果您希望编译器认为ACTIONS
本质上是不可变的,并且应该推断出可以的最窄类型,则可以在声明const
assertion时使用它:
const
现在将export const ACTIONS = {
SOMETHING: 'SOMETHING',
} as const;
的类型推断为ACTIONS
,其余代码按需进行:
{ readonly SOMETHING: "SOMETHING"; }
好的,希望能有所帮助;祝你好运!
export type ActionsType = typeof ACTIONS
export type ActionValues = ActionsType[keyof ActionsType]
export function example(keyOrValue: ActionValues) {
// ...
}
example('SOMETHING') // valid
example(ACTIONS.SOMETHING) // valid
example('') // error!
// ~~
// Argument of type '""' is not assignable to parameter of type '"SOMETHING"'