如何定义允许对象键或值的类型

问题描述 投票:0回答:1

我有一堆常量归类在对象中,但是我无法正确输入。我希望能够使用字符串或通过访问对象来传递对象属性。

我想要的是:

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

有没有一种方法可以为对象的键或值定义类型?如果是这样,如何?

typescript
1个回答
0
投票

主要问题是编译器将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"'

© www.soinside.com 2019 - 2024. All rights reserved.