制作通用接口数组

Posted

技术标签:

【中文标题】制作通用接口数组【英文标题】:Making arrays of generic interfaces 【发布时间】:2021-09-15 00:10:32 【问题描述】:

假设我们有以下界面:

interface I<A extends string, B extends string> 
    a: A,
    b: B,
    c: `$A $B`

我想创建一个函数来创建I 的数组并验证其类型,以便

makeArr([
    
        a: "1",
        b: "2",
        c: <- it should have type "1 2" | "3 4"
    ,
    
        a: "3",
        b: "4",
        c: <- it should have type "1 2" | "3 4"
    
])

我已经尝试过这样实现它:

type Arr<A extends string, B extends string> = I<A, B>[]

function makeArr<A extends string, B extends string>(arr: Arr<A, B>) 
    return arr

但是,c 属性仍然接受任何字符串

makeArr([
    
        a: "1",
        b: "2",
        c: "this does not work"
    ,
    
        a: "3",
        b: "4",
        c: "whatever "
    
])

当你明确指定类型时效果会好一些,但c 无论如何都会接受一些错误的类型

makeArr<"1" | "3", "2" | "4">([
    
        a: "1",
        b: "2",
        c: "3 2"
    ,
    
        a: "3",
        b: "4",
        c: "1 4"
    
])

我也不想明确指定它,因为这些数组可能很长​​p>

编辑: 感谢 aleksxor 的回答,我设法实现了它,但是必须明确指定类型 Playground Link

【问题讨论】:

【参考方案1】:

我相信一定有更优雅的方式。但这是我尝试实施这样的检查:

type I<T extends  a: string, b: string > = T extends 
    a: T['a'],
    b: T['b'],
    c: `$T['a'] $T['b']`
 ? T : never

function makeArr<T extends  a: string, b: string >(arr: readonly [...I<T>[]]) 
    return arr


makeArr([
    
        a: "1",
        b: "2",
        c: "doesn't pass"
    ,
    
        a: "3",
        b: "4",
        c: "3 4"
    
])

playground link

【讨论】:

我相信您的解决方案足够好和优雅。你没有看到我的) 感谢您的回答!不幸的是,它并不能完全按照我的意愿工作,因为当[ a: "1", b: "2", c: ... , a: "3", b: "4", c: ...] 传递给这个函数时,我希望能够将1 23 4 分配给这个数组条目的c 属性

以上是关于制作通用接口数组的主要内容,如果未能解决你的问题,请参考以下文章

具有开放通用和接口的 Castle Windsor 解析数组

通用网页流量记录工具

通用对象向量/数组,其中每个存储的对象都有不同的类

如何将数据组表示为通用 Typescript 接口

通用代码因 Spring 数据和 Querydsl 而失败

制作Qt应用程序的插件(使用QtPlugin),对比DLL它是全平台通用的