假设我有以下类型:

interface MyType { 
    myProperty: [a: string[], b: string[]] 
}

现在我想创建一个该类型的数组:

const array1: MyType[] = [
    {myProperty: [["Hello", "World"], []]},
    {myProperty: [["Hello"], []]},
];

如果我try 对该数组进行排序:

const array2: MyType[] = [
    {myProperty: [["Hello", "World"], []]},
    {myProperty: [["Hello"], []]},
].sort((a,b) => a.myProperty[0].length - b.myProperty[0].length);

我得到一个错误:

Type '{ myProperty: string[][]; }[]' is not assignable to type 'MyType[]'.

我try 了各种解决方案:

  • 使用排序初始化数组(Lambda)

    const array2: MyType[] = [
        {myProperty: [["Hello", "World"], []]},
        {myProperty: [["Hello"], []]},
    ].sort((a,b) => a.myProperty[0].length - b.myProperty[0].length);
    

    值没有正确的类型

  • 使用排序初始化数组(函数)

    const array3: MyType[] = [
        {myProperty: [["Hello", "World"], []]},
        {myProperty: [["Hello"], []]},
    ].sort(compareMyType);
    function compareMyType(a: MyType, b: MyType) { 
        return a.myProperty[0].length - b.myProperty[0].length; 
    }
    

    排序函数没有正确的类型并且值没有正确的类型

  • 选角至MyType[]:

    const array4: MyType[] = ([
        {myProperty: [["Hello", "World"], []]},
        {myProperty: [["Hello"], []]},
    ] as MyType[]).sort(compareMyType);
    const array5: MyType[] = ([
        {myProperty: [["Hello", "World"], []]},
        {myProperty: 5},
    ] as MyType[]).sort(compareMyType);
    

    铸造 suppress 可能导致运行时错误的错误

  • 排序已初始化的数组

    const array1: MyType[] = [
    
        const array2: MyType[] = [
        {myProperty: [["Hello", "World"], []]},
        {myProperty: [["Hello"], []]},
    ];
    
    const array6: MyType[] = array1.sort(compareMyType);
    

    没有错误.

为什么这有效,而其他try 却无效(编译器或运行时错误)?有更好的/其他解决方案吗?

Playground

推荐答案

绊脚石是TypScript的默认行为是将array literal的类型推断为普通数组类型,而不是tuple. TypScript的contextual typing通常不通过函数调用工作,因此虽然const arr: MyType[] = [⋯]将有适当的上下文来成功,但const arr: MyType[] = [⋯].sort(⋯)不会.

在这里继续进行的最佳方法可能是使用the satisfies operator而不是type assertion:

const arr: MyType[] = ([
    {myProperty: [["Hello", "World"], []]},
    {myProperty: [["Hello"], []]},
] satisfies MyType[]).sort(compareMyType);

您可以使用satisfies为类型推断提供上下文,而不会失go 类型安全性.

Playground link to code

Typescript相关问答推荐

如何将单元测试中的私有订阅变量设置为空(或未定义)?

参数类型undefined不能分配给参数类型字符串|未定义

typescribe不能使用值来索引对象类型,该对象类型满足具有该值的另一个类型'

在泛型类型中对子代执行递归时出错

Redux—Toolkit查询仅在不为空的情况下添加参数

泛型函数中输入参数类型的推断问题

如何在TypeScrip中使用嵌套对象中的类型映射?

泛型类型联合将参数转换为Never

TypeScrip表示该类型不可赋值

TypeScrip-将<;A、B、C和>之一转换为联合A|B|C

如何判断对象是否有重叠的叶子并产生有用的错误消息

为什么有条件渲染会导致material 自动完成中出现奇怪的动画?

以Angular 执行其他组件的函数

如何以Angular 导入其他组件S配置文件

在TypeScript中扩展重载方法时出现问题

声明遵循映射类型的接口

如何通过转换器类继承使用多态将对象从一种类型转换为另一种类型

在打印脚本中将对象类型转换为数组

可以用任意类型实例化,该类型可能与

类型分布在第一个泛型上,但不分布在第二个泛型上