根据他们的wiki, TypeScript 3.0引入了未知类型:
Unknown现在是一个保留类型名,因为它现在是一个内置类型。 根据unknown的预期用途,可能需要删除 完全声明(支持新引入的未知类型),或者 将其重命名为其他内容。
未知和任何的区别是什么?什么时候用unknown代替any?
根据他们的wiki, TypeScript 3.0引入了未知类型:
Unknown现在是一个保留类型名,因为它现在是一个内置类型。 根据unknown的预期用途,可能需要删除 完全声明(支持新引入的未知类型),或者 将其重命名为其他内容。
未知和任何的区别是什么?什么时候用unknown代替any?
当前回答
unknown和any的区别如下:
就像any一样,any值可以赋值给unknown;但是,与any不同的是,您不能访问类型未知的值上的任何属性,也不能调用/构造它们。此外,unknown类型的值只能赋值给unknown或any。
要回答你什么时候应该用unknown代替any的问题:
这对于想要发出“这可以是任何值”信号的api非常有用 在使用它之前,您必须执行某种类型的检查”。这就迫使 用户可以安全地自省返回值。
看看TypeScript 3.0公告中关于类型检查未知变量的例子,以及更详细的解释。
其他回答
未知的
如果编写的函数只将输入传递给另一个函数,请使用unknown。从函数的角度来看:“我不知道,我不想知道”。使用unknown并没有错。
例如:
function buy(item: unknown): Purchase {
if (item) {
return purchase(item);
} else {
throw new TypeError('item is missing');
}
}
Any
如果需要在该值上调用属性,那么任何一个都更合适。
Linting可能不喜欢任何一个,建议你的输入更具体。这样,如果您将接口从isItem更改为isValid, typescript会告诉您更新代码。
例如:
// 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;
如果你感兴趣,请参阅用户定义守卫,我带来了它,因为这是我需要的少数情况之一。
这篇来自ultimatecourses的博客:
如果没有其他选项,请使用any类型
任何一个都很难找到好的例子。
公认的答案是“未知,它是any的类型安全对应物。”
然而,正如这个例子所示,unknown是它自己的野兽,有时它的行为与其他动物非常不同:
type Foo = unknown extends string ? true : false // false
type Bar = any extends string ? true : false // boolean - i.e. both true and false
它们在语义上有所不同。
Unknown是所有其他类型的父类型。它是类型系统中的常规类型。
Any表示“关闭类型检查”。它是一个编译器指令和一种元编程。
我是姗姗来迟,但我会尽力揭开它的神秘面纱。
const canBeAnything: any = 100;
const canNotBeAnything: unknown = 100;
// If we try to use a .startsWith() method
canBeAnything.startsWith('10'); // no error
canNotBeAnything.startsWith('10'); // Property 'startsWith' does not exist on type 'unknown'
在unknown上使用.startsWith()方法的唯一方法是显式地告诉编译器类型,例如
(canNotBeAnything as string).startsWith('10'); // Chill down TS compiler, I know what I am doing.
后面的on不会显示任何编译错误,但它会在运行时抛出错误,因为canNotBeAnything是一个数字类型,我们强制它为字符串
任何未知的:
允许分配任何类型
any:
允许被分配给任何类型 允许调用任何方法
无名:
不允许被赋给任何类型 不允许调用任何方法
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