any 和 any[ ] 有啥区别?

Posted

技术标签:

【中文标题】any 和 any[ ] 有啥区别?【英文标题】:What is the difference between any and any[ ]?any 和 any[ ] 有什么区别? 【发布时间】:2017-10-19 12:59:30 【问题描述】:

any和any[ ]有什么区别?


示例 1(按预期工作)

name1: any;
name2: any[];
this.name1 = this.name2;

示例 2(这也按预期工作)

name1: any;
name2: any[];
this.name2 = this.name1;

为什么允许any 数据类型的打字稿可以访问any[] 数据类型。和any[]一样的数据类型可以访问any类型的数据吗?和哪个最好用?如果数据类型只是像string or number or object or any这样的对象(不是数组),那么为什么any[ ]会接受该对象类型而不显示任何运行时或编译时错误?


【问题讨论】:

好吧..它可以是任何东西或任何东西的数组(这有点没有意义,因为任何东西也可以是任何东西的数组)。 any 类型是禁用代码位类型检查的打字稿方式。 是的,这是您在使用 typescript 时可能遇到的唯一问题 我认为这是个好问题。应该是编译时错误,至少对于 noImplicitAny。然而,打字稿团队似乎愿意放宽类型严格性以支持现有代码。不利于语言恕我直言。 【参考方案1】:

如果我们看一下这个 TypeScript 代码:

let name1: any = "John";
let name2: any[] = ["Mary", "Sue", "Sally"];
name1 = name2;

let name3: any[] = ["Luke", "Paul", "Ringo"];
let name4: any = "Mark";
name3 = name4;

它编译成的javascript是:

var name1 = "John";
var name2 = ["Mary", "Sue", "Sally"];
name1 = name2;
var name3 = ["Luke", "Paul", "Ringo"];
var name4 = "Mark";
name3 = name4;

JavaScript 变量是动态的,没有固定类型。我可以想象这个可能会被 TypeScript 编译器报告为警告或错误,但这不会停止 JavaScript 的生成或阻止 JavaScript 运行。

因此,虽然any/any[] 分配当前没有编译错误或警告,但any[] 仍可用于告知开发人员期望。

注意:这不是我会编写或建议任何人使用的代码。这只是带有值的 OP 代码,并显示了生成的 JavaScript 将是什么,并且因为它编译为 JavaScript,所以不会因类型而出现运行时错误,因为变量具有动态类型。这也是我们选择使用 TypeScript 的原因之一:编译时静态类型检查。出于这个原因,人们通常会避免使用anyany[] 来支持更好地表示数据的类或接口。在这种情况下,stringstring[](或任何其他类型)显示编译器错误。

在此示例中,name1 = name2name3 = name4 都是编译时错误,因为变量从赋值中推断类型,并且它们的用法在后续代码中进行类型检查。

let name1 = "John";
let name2 = ["Mary", "Sue", "Sally"];
name1 = name2; //Type 'string[]' is not assignable to type 'string'.

let name3 = ["Luke", "Paul", "Ringo"];
let name4 = "Mark";
name3 = name4; //Type 'string' is not assignable to type 'string[]'.

【讨论】:

说得好。一个很好的答案。【参考方案2】:

如果你在赋值的左边和右边都使用any,你基本上是说Typescript不使用类型检查。

any 位于左侧,这意味着您要分配值的变量可以接受任何类型,因此它接受任何类型的对象,包括 any[] 类型的对象。

如果 any 类型在右侧,而 myVar: any[] 在左侧,则基本上是说 Typescript 不使用类型检查。考虑到在运行时不应用类型检查,您最终会得到 myVar 被填满作业右侧的任何内容。

【讨论】:

是的!但我非常谦虚的问题是。如果数据不是数组,它只是一个对象,那么为什么 any[] 将接受该类型?至少它应该抛出一个运行时错误?但不是,为什么? @RameshRajendran,因为它编译为 Javascript,你怎么会期望出现运行时错误(变量没有静态类型)?【参考方案3】:
    仅 Any 用于任何类型的单个对象。 Any[] 用于 Any 类型的对象数组。

【讨论】:

【参考方案4】:

any 和 any[] 的区别在于智能。

var a:any = .....

a.map , a.join (no intellisense, typescript does not know if a is an array or not)


var a:any[] = ....
a.map , a.join (typescript knows that a is an array and will provide intellisence)

编译时错误

var aa:any[] = "a"; // error typescript will not allow this

var a:any = "a"; // a can be string, there is no harm

aa = a; // typescript cannot detect error at 
        // compile time because a can be array

var someString:string;

aa = someString; // typescript knows that aa is an array and someString is not

通过声明any[],您是在告诉我我希望这个对象是数组类型。然而,any 就是任何东西,甚至数组也可以是 any,所以 typescript 允许您将 any 分配给任何数组。

TypeScript 会尽可能检测编译时错误,但是当您将某些内容设置为 any 时,它不会检测到编译时错误。

编译器设计者是否强制执行此类编译时错误,我想不应该允许以下操作,

 a:any 
 aa:any[] = a; // this should be compile time error

为避免这种情况,当然可以将其转换为 aa = a as any[],就像在 C# 和 Java 等语言中一样。

运行时错误

JavaScript 没有关于变量声明的类型规范,因此 JavaScript 引擎对类型没有任何概念。

只有当你调用一个方法或访问属性时,JavaScrip 才会给你一个错误..

a:any[] ..

// this will give an error TypeError: .map is not a function
a.map( ()=> ... )

a.length // this is undefined.. any member of any object is
// essentially undefined, there is no type error when you access
// member

【讨论】:

以上是关于any 和 any[ ] 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Mockito Matchers isA、any、eq 和 same 有啥区别?

Assert.Empty(msgs) 和 Assert.False(msgs.Any()) 有啥区别?

TypeScript 中 unknown 与 any 有啥区别

Array 和 Observable Array 有啥区别?

vs2012 发布网站Release发布模式 any cpu 与.net与mixed platforms 有啥区别?

sql中any和all的区别?