代码之家  ›  专栏  ›  技术社区  ›  majelbstoat

如何从Typescript中固定对象的键创建映射类型

  •  5
  • majelbstoat  · 技术社区  · 7 年前

    我有一个这样的物体:

    const routes = {
      home: { path: '/', page: 'home' },
      profile: { path: '/profile', page: 'users/profile' }
    }
    

    我想从中定义一个派生类型,如下所示:

    type RouteName = keyof typeof routes ,这将创建一个 "home" | "profile" .

    然而,我不能这样做:

    for (let name in routes) {
      router.add({ name, ...routes[name]})
    }
    

    因为编译器抱怨 routes[name] 属于隐式类型 any :

    Element implicitly has an 'any' type because type '{ home: { path: string; page: string; }; profile: { path: string; page: string; };' has no index signature.
    

    如果我将管线定义修改为:

    interface RouteDefinition {
      path: string
      page: string
    }
    const routes: {[key: string]: RouteDefinition} = {
      home: { path: '/', page: 'home' },
      profile: { path: '/profile', page: 'users/profile' }
    }
    

    生成的类型 类型RouteName=路由类型的键 现在是 string 而不是 "home"|"profile" .

    我当然可以定义一个硬编码的 RouteName 类型,但如果不清楚,我会尽量避免在两个位置定义路由名称,尤其是当对象的键严格定义了一组可能性时。

    对象只需定义一次,不需要重新分配。我尝试了很多组合 Readonly<> ,铸造等,但无法理解。有没有办法做到这一点?

    (我使用的是Typescript 2.8.1)

    1 回复  |  直到 7 年前
        1
  •  10
  •   Aaron Beall    7 年前

    TypeScript认为这样假设是不安全的 for..in 键正是在类型中定义的键,因为在JavaScript中所有对象都是打开的。

    您可以使用断言消除编译错误:

    for (let name in routes) {
      routes[name as RouteName]; // no error
    }
    

    或者,我会把你的两种方法结合起来。您可以定义 routes 在执行此操作时,将密钥提取为 RouteName ,但也可以 RouteDefinition 并在要映射路由时,将路由分配给索引类型(可以使用对新变量或函数参数的断言来完成):

    interface RouteDefinition {
        path: string;
        page: string;
    }
    
    const routes = {
        home: { path: '/', page: 'home' },
        profile: { path: '/profile', page: 'users/profile' }
    }
    
    type RouteName = keyof typeof routes;
    
    mapRoutes(routes);
    
    function mapRoutes(routes: { [key: string]: RouteDefinition }) {
        for (let name in routes) {
            routes[name] // no error
        }
    }
    

    如果您的 路线 文字不满足 路由定义 (缺少一个键,键的类型错误)然后你会在分配站点出错,即 mapRoutes(routes) 在上面

    推荐文章