TypeScript:如何使 keyof typeof 返回字符串而不是没有循环引用的键

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

对于下面的代码,我想提取

routes
的键。


type Route = {
  url: string
  auth: boolean
}

type Routes = Record<string, Route>

const routes: Routes = {
    add: {
        url: '/comment',
        auth: false
    },
    delete: {
        url: '/comment',
        auth: true
    }
}

如果我将键定义为:

type RouteKeys = keyof typeof routes

RouteKeys 转换为

string
,因为从
Record<string>
推断,很好 - 但我希望它是
'add' | 'delete'

当我尝试时:

type Routes = Record<keyof typeof routes, Route>

然后我收到一个 TypeScript 错误“类型别名路由循环引用自身”,这也很公平。

如果我定义的话我明白:

type RouteKeys = 'add' | 'delete'

并将其分配给路线它会起作用,但这将迫使我在每次有新路线时手动更改类型。或者,我被迫放弃“路线”中的“路线”类型,这并不理想,因为我有条件地进一步研究这种类型。

有没有一种方法可以获取密钥并保留“路由”类型,而无需在任何地方对其进行硬编码,同时还可以保留指定的路由类型值?

typescript typeof keyof
1个回答
0
投票

您可以使用

satisfies
运算符来保证
routes
的属性值都可以分配给
Route

const routes = {
    add: {
        url: '/comment',
        auth: false
    },
    delete: {
        url: '/comment',
        auth: true
    }
} satisfies { [k: string]: Route }

这打破了潜在的循环,所以现在你可以用

Routes
来定义
typeof routes

type Routes = Record<keyof typeof routes, Route>

在此版本中,

routes
的类型比
Routes
稍窄,因为这些值可能是
Route
的子类型。如果您需要
routes
完全属于
Routes
类型,您可以随时将其重命名以方便开始,然后复制结果:

const _routes = {
    add: {
        url: '/comment',
        auth: false
    },
    delete: {
        url: '/comment',
        auth: true
    }
} satisfies { [k: string]: Route }        
type Routes = Record<keyof typeof _routes, Route>    
const routes: Routes = _routes;

Playground 代码链接

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