Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 为什么允许这样做?常量nums:number[]={…[1,2,3]}_Typescript - Fatal编程技术网

Typescript 为什么允许这样做?常量nums:number[]={…[1,2,3]}

Typescript 为什么允许这样做?常量nums:number[]={…[1,2,3]},typescript,Typescript,刚刚在我的typescript代码库中发现了一个关键错误,因为这是允许的: const nums: number[] = { ...[1, 2, 3] } // should have been [ ...[1,2,3] ] a.join('-') // runtime error: a.join is not a function 为什么一个数组被解构为一个对象,可以分配给一个数组,而这个数组会导致一个容易预防的运行时异常?这是TypeScript的一个设计限制;看 类型系统无法将接口成

刚刚在我的typescript代码库中发现了一个关键错误,因为这是允许的:

const nums: number[] = { ...[1, 2, 3] } // should have been [ ...[1,2,3] ]
a.join('-')
// runtime error: a.join is not a function 


为什么一个数组被解构为一个对象,可以分配给一个数组,而这个数组会导致一个容易预防的运行时异常?

这是TypeScript的一个设计限制;看

类型系统无法将
接口
成员标记为“自有”或可枚举,因此编译器假定所有成员都是通过扩展运算符复制的。作为一种启发式方法,这通常是足够的,但对于原型上设置的任何成员(如类的方法),这都是错误的:

interface Whoops {
    foo(): void;
    a: number;
    b: string;
}

class Oops implements Whoops {
    foo() { }
    a = 1;
    b = "";
}

const oopsie = (w: Whoops) => ({ ...w });

oopsie(new Oops()).foo(); // no compiler error
// runtime error: oopsie(...).foo is not a function!
如果您直接编写
声明,编译器将假定方法声明不可扩展:

declare class Whoops {
    foo(): void;
    a: number;
    b: string;
}
const oopsie = (w: Whoops) => ({ ...w });
oopsie(new Whoops()).foo(); // compiler time error as expected
// foo does not exist on {a: number; b: string};
但不幸的是,这并不是一个好消息。因此,当您将数组扩展到一个对象中时,编译器认为所有的
array
属性和方法都被复制,因此生成的对象符合
array
接口,因此具有一个
join()
方法。哎呀


Maaay也许有人可以更改标准库,这样就不再使用
interface Array
interface ArrayConstructor
declare var Array:ArrayConstructor
了,我们刚刚使用了
declare class Array
,然后
join()
将不再被认为是可扩展的,但我不确定。当我在自己的系统上本地尝试它时,它似乎可以工作,但我不能在操场或其他在线IDE中轻松地复制它,而且我无论如何都不喜欢使用内置类型,如
数组

或者Maaaybe可以更改语言,以便在
接口
s上标记非自有或不可枚举的属性,但我不会指望它(请参阅)

目前,这是TypeScript的设计限制。如果您对此有强烈的感受,可以访问microsoft/TypeScript#34780并对其进行测试