TypeScript 3.0根据其Wiki引入了unknown
类型:
unknown现在是保留类型名称,因为它是内置类型。 根据未知的用途,您可能希望删除 完全声明(有利于新引入的未知类型),或 将其重命名为其他名称。
unknown
和any
有什么区别?什么时候应该在unknown
上使用any
?
答案 0 :(得分:99)
您可以在PR或RC 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
的值只能分配给unknown
或any
。
要回答何时在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
找到好的例子。