Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/479.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

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
Javascript 在Typescript中,为什么一个对象不能在赋值时指定多余的属性,但当使用相同的接口传递给函数时却可以指定多余的属性?_Javascript_Typescript - Fatal编程技术网

Javascript 在Typescript中,为什么一个对象不能在赋值时指定多余的属性,但当使用相同的接口传递给函数时却可以指定多余的属性?

Javascript 在Typescript中,为什么一个对象不能在赋值时指定多余的属性,但当使用相同的接口传递给函数时却可以指定多余的属性?,javascript,typescript,Javascript,Typescript,我已经添加了给我错误的代码,您将在底部的对象分配中看到错误 interface Car { make: string, model: string, year: number } function repairCar(car: Car) { } let myCar = { make: 'Honda', model: 'Accord', year: 1992, color: 'red' } repairCar(myCar); 但当我

我已经添加了给我错误的代码,您将在底部的对象分配中看到错误

interface Car {
    make: string,
    model: string,
    year: number
}

function repairCar(car: Car) {

}

let myCar = {
    make: 'Honda',
    model: 'Accord',
    year: 1992,
    color: 'red'
}

repairCar(myCar);
但当我添加此代码时:

let myCar2: Car = {
    make: 'Honda',
    model: 'Accord',
    year: 1992,
    color: 'red'
}
我得到这个错误:

键入“{make:string;model:string;year:number;color:string;}” 不可分配给类型“Car”。对象文字只能指定 已知属性,并且类型“Car”中不存在“color”


我不明白为什么它被允许在传递给repairCar函数的对象上拥有多余的属性,但当它被分配给一个具有类型注释的变量时,它是同一个接口。

想象一下它可以正常工作:

  let myCar2: Car = {
    make: 'Honda',
    model: 'Accord',
    year: 1992,
    color: 'red'
 };
那么颜色属性就完全没有意义了,因为:

 console.log(myCar2.color);
不起作用,因为颜色不是车型的一部分

为什么允许在传递给repairCar函数的对象上有多余的属性

因为您可以将具有附加属性的对象传递给函数,而不会产生任何副作用,并且仍然可以在其他位置使用颜色属性:

 repairCar(myCar);
 console.log(myCar.color); 
现实世界的例子:把鸟叫做动物是没有意义的,因为如果它只是一种动物,它就不会飞,这就是为什么我们叫鸟而不是动物。然而,如果你说动物可以移动,那么鸟也可以移动,因为它是动物


如果要解决此错误,只需将颜色设置为可选颜色,或使用超类型:

 interface ColoredCar extends Car {
   color: string;
 }

 // or

 interface Car {
  make: string,
  model: string,
  year: number
  color?: string;
 }

Typescript中的对象只允许具有类型中指定的字段。与其他语言不同,我们不能定义变量来存储子类。因此,我们得到一个写入错误

interface Car = {
    make: string,
    model: string,
    year: number
}

let myCar: Car = {
    make: 'Honda',
    model: 'Accord',
    year: 1992,
    color: 'red'
}
但是,Typescript允许我们使用具有方法所需的所有字段的对象调用方法。允许这样做不会破坏该方法,因为子类必须实现该方法所需的所有字段。因此,我们可以写作

interface ColoredCar extends Card {
    color: string
}

let myColoredCar: ColoredCar = {
    make: 'Honda',
    model: 'Accord',
    year: 1992,
    color: 'red'
}

function repairCar(car: Car) {
     // Implementation...
}

// Doesn't matter for the method repairCar if myColoredCar is a ColoredCar or a Car as 
// long as make, model and year are defined
repairCar(myColoredCar);

在编译时验证创建类型化对象。这一部分对于任何静态类型语言都是正常的。
它正在为动态obj执行隐式转换,并且由于包含必需的字段而成功。但是它不必是汽车类型的对象。

看看“多余的属性检查”部分:对象文本被给予了特别的考虑。没有意义吗?在这种情况下,当将同一对象传递给具有相同类型注释权限的函数时,使用同一对象也会出错?为什么我的不同asking@eric因为它们可以在其他地方使用,所以将其传递给具有其他属性的函数并非毫无意义。当你说它们可以在其他地方使用时,我不理解你的推理。可以访问该属性,并在指定的其他位置使用该属性well@eric不,不能。您键入它是为了使它不能被使用。是的,因为它会出错,但请告诉我,为什么Typescript会决定将完全相同的对象分配给同一类型的接口时会出错,而将该对象传递给键入到同一接口的函数时则不会出错。为什么该属性允许在该函数的“其他地方”使用,但如果在该函数外部使用,则不能使用?TypeScript对对象参数进行编译时检查,它确保对象具有接口的属性,或者classIt正在为动态obj执行隐式转换,并且由于包含必需的字段,因此该操作成功。但它不必是汽车类型的对象。