TypeScript:推断带注释对象内部类型的泛型

奥利弗·约瑟夫·阿什

我有一个名为的通用类型RouteConfig,我试图在名为的对象内部使用routes

// Generic type
type RouteConfig<Params> = {
    path: string;
    component: (params: Params) => string;
};

type Route = 'Home' | 'User';

// Object
const routes: Record<Route, RouteConfig<unknown>> = {
    Home: {
        path: 'a',
        // False positive (should not error)
        component: (params: { foo: string }) => 'x',
    },
    User: {
        path: 'a',
        // False positive (should not error)
        component: (params: { bar: string }) => 'z',
    },
};

对象内部的每个值都可以为的Params内部类型具有自己的类型RouteConfig

我的问题是:在routes类型注释中,应该将泛型传递给RouteConfig什么?

我无法提供单一类型,因为每个对象值都可以具有自己的类型。(一个联合会将相同的联合类型应用于所有对象值,这不是我想要的。)

在上面的示例中,我使用unknown,但是这会导致错误的肯定类型错误(请参见上面的代码示例中的注释)。

我无法使用,any因为这样一来,从对象读取数据时我就失去了类型安全性:

const routes: Record<Route, RouteConfig<any>> = {
    Home: {
        path: 'a',
        // True negative
        component: (params: { foo: string }) => 'x',
    },
    User: {
        path: 'a',
        // True negative
        component: (params: { bar: string }) => 'z',
    },
};

// True negative
routes.Home.component({ foo: 'abc' });

// False negative (should error)
routes.Home.component({ bar: 'abc' });

我可以从中删除类型注释routes

const routes = {
    Home: {
        path: 'a',
        // True negative
        component: (params: { foo: string }) => 'x',
    },
    User: {
        path: 'a',
        // True negative
        component: (params: { bar: string }) => 'z',
    },
};

// True negative
routes.Home.component({ foo: 'abc' });

// True positive
routes.Home.component({ bar: 'abc' });

…但是后来我失去了诸如的类型和属性的“查找引用”和“重命名”之类的便利RouteConfig此外,由于TypeScript将不再能够检查对象是否包含所有必需的键(由Route类型定义,因此我将失去类型安全性

我认为我正在寻找的是一种注释routes对象类型(泛型除外)的方法-泛型应从对象定义中推断出来。

总而言之,我正在寻找一种编写方法来实现以下所有目的:

  • 好的开发用户体验:
    • 如果我在中重命名属性RouteConfig,更改是否适用于所有用法?
    • 我可以在中找到某个属性的所有引用RouteConfig吗?
  • 无意外错误
  • 类型安全性(预期错误)

有什么办法可以实现上述所有目的?

TS游乐场

提香·切尔尼科娃·德拉戈米尔

同时获得所有这三个元素并非完全简单。我使用它的一种方法是使用一个额外的函数进行推理(以捕获对象文字的实际类型),然后对输入和输出类型进行一些重做。通过将输入添加& Record<Route, RouteConfig<any>>到参数类型以使ts知道ts的输入值RouteConfig<any>(否则ts会在重命名期间错过这些),并且输出类型i实质上通过了一个标识类型,以确保对refrefRouteConfig的保留。输出(没有此用法的站点将在重命名中丢失):


type RouteConfig<Params> = {
    path: string;
    component: (params: Params) => string;
};

type Route = 'Home' | 'User';
type RouteHelper<T extends Record<Route, RouteConfig<any>>> = {
    [P in keyof T] : RouteConfig<T[P] extends RouteConfig<infer P> ? P : never>
}
function createRoutes<T extends Record<Route, RouteConfig<any>>>(r: T & Record<Route, RouteConfig<any>>):  RouteHelper<T>{
    return r as any;
}


// [✅] Good dev UX
// [✅] No unexpected errors
// [✅] Type safety (errors when expected)

{
    const routes = createRoutes({
        Home: {
            path: 'a',
            // True negative
            component: (params: { foo: string }) => 'x',
        },
        User: {
            path: 'a',
            // True negative
            component: (params: { bar: string }) => 'z',
        },
    });

    // True negative
    routes.Home.component({ foo: 'abc' });

    // True positive
    routes.Home.component({ bar: 'abc' });
}

游乐场链接

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

内部类/接口中定义的泛型类型是否绑定到外部类的泛型类型定义?

来自分类Dev

当使用Lambda表达式而不是匿名内部类时,Spring无法确定泛型类型

来自分类Dev

Swift泛型类型推断扩展

来自分类Dev

Swift中泛型的类型推断

来自分类Dev

Java泛型,类型推断,继承?

来自分类Dev

Scala是否支持内部类泛型

来自分类Dev

泛型类作为带有内部类型的参数

来自分类Dev

comman的C#泛型类型推断

来自分类Dev

TypeScript泛型:参数类型推断

来自分类Dev

如何引用内部类成员的泛型类型?

来自分类Dev

Typescript泛型:从函数参数的类型推断类型?

来自分类Dev

Typescript:在可选的第一个泛型之后推断泛型的类型

来自分类Dev

Typescript推断泛型中的泛型

来自分类Dev

输入泛型推断类型的数组

来自分类Dev

指定其他类型时,如何让TypeScript推断受约束的泛型类型的值?

来自分类Dev

是否可以在TypeScript中递归地推断泛型类型?

来自分类Dev

带返回值的泛型函数参数的TypeScript参数类型推断?

来自分类Dev

Typescript编译器使用泛型推断类型

来自分类Dev

如何在C#中对具有抽象内部类型的泛型进行模式匹配?

来自分类Dev

从嵌套类型推断泛型

来自分类Dev

Java中用于内部类的泛型类型

来自分类Dev

从泛型推断类型

来自分类Dev

泛型类作为带有内部类型的参数

来自分类Dev

Swift 泛型类型推断

来自分类Dev

带泛型的命令对象

来自分类Dev

TypeScript 类型注释来表达可变数量的泛型?

来自分类Dev

类型推断:泛型,“var”

来自分类Dev

泛型类型推断的 Typescript 泛型

来自分类Dev

从参数推断泛型类型

Related 相关文章

热门标签

归档