“未知”与“任何”

时间:2018-07-20 09:50:26

标签: typescript typescript3.0

TypeScript 3.0根据其Wiki引入了unknown类型:

  

unknown现在是保留类型名称,因为它是内置类型。   根据未知的用途,您可能希望删除   完全声明(有利于新引入的未知类型),或   将其重命名为其他名称。

unknownany有什么区别?什么时候应该在unknown上使用any

6 个答案:

答案 0 :(得分:99)

您可以在PRRC announcement中阅读有关unknown的更多信息,但要旨是:

  

[..] unknown,它是任何类型安全的副本。任何东西都可以分配给未知对象,但是除了本身以及没有类型声明或基于控制流的缩小对象之外,未知对象都不能分配给其他对象。同样,在未声明或缩小为更具体的类型之前,不允许对未知数进行任何操作。

一些例子:

let vAny: any = 10;          // We can assign anthing to any
let vUnknown: unknown =  10; // We can assign anthing to unknown just like any 


let s1: string = vAny;     // Any is assigable to anything 
let s2: string = vUnknown; // Invalid we can't assign vUnknown to any other type (without an explicit assertion)

vAny.method();     // ok anything goes with any
vUnknown.method(); // not ok, we don't know anything about this variable

建议的用法是:

  

很多时候,我们想在TypeScript中描述功能最差的类型。这对于希望表示“可以是任何值,因此使用前必须执行某种类型的检查”的API很有用。这迫使用户安全地检查返回的值。

答案 1 :(得分:14)

unknown与any之间的差异描述为:

  

any类似,任何值都可以分配给unknown;但是,与any不同,您不能访问类型为unknown的值的任何属性,也不能调用/构造它们。此外,类型unknown的值只能分配给unknownany

要回答何时在unknown上使用any的问题:

  

这对于想要发出“可以是任何值的信号”的API很有用。   您必须在使用前进行某种检查”。这种力量   用户可以安全地检查返回的值。

TypeScript 3.0 announcement中查看类型检查unknown类型变量的示例以及更详细的说明。

答案 2 :(得分:7)

any类型:

any类型表示所有可能的JS值。每种类型均可分配给类型any。因此,类型any是类型系统的通用超类型。 TS编译器将允许对类型为any的值进行任何操作。例如:

let myVar: any;

myVar[0];
myVar();
myVar.length;
new myVar();

在许多情况下,这对于TS编译器来说太宽容了。即它将允许我们可能会导致运行时错误的操作。

unknown类型:

unknown类型表示(就像any一样)所有可能的JS值。每种类型均可分配给类型unknown。因此,类型unknown是类型系统的另一个通用超类型(与any并存)。但是,TS编译器不允许允许对类型为unknown的值进行任何操作。此外,unknown类型只能分配给类型any。一个例子将阐明这一点:

let myVar: unknown;

let myVar1: unknown = myVar;   // No error
let myVar2: any = myVar;       // No error
let myVar3: boolean = myVar;   // Type 'unknown' is not assignable to type 'boolean'

// The following operations on myVar all give the error:
// Object is of type 'unknown'
myVar[0];
myVar();
myVar.length;
new myVar();

答案 3 :(得分:3)

它们在语义上是不同的。

unknown 是所有其他类型的父类型。这是语法上的常规类型。

any 表示“关闭类型检查”。这是一种元编程。

答案 4 :(得分:2)

任何未知:

  • 允许分配任何类型

任何:

  • 允许分配给任何类型
  • 允许调用任何方法

未知:

  • 不允许分配给任何类型
  • 不允许调用任何方法
const a: any = 'a'; // OK
const b: unknown = 'b' // OK

const v1: string = a; // OK
const v2: string = b; // ERROR
const v3: string = b as string; // OK

a.trim() // OK
b.trim() // ERROR

答案 5 :(得分:0)

未知

如果您编写的函数只将输入传递给另一个函数,请使用 unknown。从功能的角度来说:“我不知道,我不想知道”。使用 unknown 没有任何问题。

例如:

function buy(item: unknown): Purchase {
  if (item) {
    return purchase(item);
  } else {
    throw new TypeError('item is missing');
  }
}

任何

如果您需要对该值调用属性,那么 any 更适合。

Linting 可能不喜欢 any,建议您更具体地输入您的意见。这样,如果您将界面从 isItem 更改为 isValid,打字稿会告诉您更新代码。

例如:

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function isItem(item: any): item is Purchase {
  return !!item?.price;
}

调用属性

function isStuff(item: unknown): item is Stuff {
  return (item as Stuff).it !== undefined;
}
function isStuff(item: any): item is Stuff {
  return item.it !== undefined;
}
camelcaseKeys(item) as unknown as Item;

如果您有兴趣,请参阅 user defined guards,我把它带来了,因为它是我需要的少数情况之一。

来自 ultimatecourses 的这篇博客:

<块引用>

当没有其他选项时使用 any 类型

很难为 any 找到好的例子。