TypeScript 3.0 `unknown` 类型作为 `any` 或 `generics` 的替代品?
Posted
技术标签:
【中文标题】TypeScript 3.0 `unknown` 类型作为 `any` 或 `generics` 的替代品?【英文标题】:TypeScript 3.0 `unknown` type as an alternative to `any` or `generics`? 【发布时间】:2019-01-05 06:20:00 【问题描述】:https://blogs.msdn.microsoft.com/typescript/2018/07/12/announcing-typescript-3-0-rc/#the-unknown-type
TypeScript 3.0 引入了一种名为
unknown
的新类型,它正是这样做的。很像any
,任何值都可以分配给unknown
;但是,与any
不同,您不能访问类型为unknown
的值的任何属性,也不能调用/构造它们。此外,unknown
类型的值只能分配给unknown
或any
。例如,将上面的示例替换为使用
unknown
而不是any
会强制将所有对 foo 的使用变为错误:
let foo: unknown = 10;
// Since `foo` has type `unknown`, TypeScript
// errors on each of these usages.
foo.x.prop;
foo.y.prop;
foo.z.prop;
foo();
new foo();
upperCase(foo);
foo `hello world!`;
function upperCase(x: string)
return x.toUpperCase();
我最近开始使用 TypeScript 进行编码,这是我的问题:
1。在我看来,unknown
可以完全替代any
。
当然,用原生 javascript 编写的代码需要在 TypeScript 中自动使用 any
类型,但是当我们从头开始使用纯 TypeScript 编写代码时,是否有任何理由使用 any
类型而不是 unknown
从 3.0 版开始?
2。 unknown
和 generics
有什么区别?
例如,
const A = <T>(value: T): T => value;
const A1 = (value: unknown) => value;
console.log(A<string>('Hello'), A<number>(100));
const B = <T, U>(t: T, u: U) =>
console.log(t);
console.log(u);
;
const B1 = (t: unknown, u: unknown) =>
console.log(t);
console.log(u);
;
B<string, number>('Hello', 100);
B<number, string>(100, 'Hello');
并假设参数value: unknown
最初是明确类型的,值的类型已确定,所以在我看来没有理由明确传递T
。
谢谢。
【问题讨论】:
【参考方案1】:关于您问题的第一部分,在大多数情况下,我可能会使用unknown
而不是any
,最好在必要时使用明确的断言,以使程序员意识到某些东西不一定安全。 any
的一个大问题是人们在不知不觉中将其分配给预期错误的类型变量或参数:
function foo() :any return 1;
let x:string = foo () ;
x.bold() // runtime error
上述任何代码都会导致运行时错误
function foo() : unknown return 1;
let x:string = foo () ; // compile time error we need to think about why we are doing this.
使用上面的代码,我们必须使用显式断言来使其工作,并思考为什么我们将foo
的结果断言为字符串
也许这 answer 关于两者之间的区别也有帮助
关于这种蜜蜂是泛型的替代品,它不是。首先你应该避免指定显式类型参数,大多数时候编译器会为你推断它们。
const A = <T>(value: T): T => value;
const A1 = (value: unknown) => value;
// redundant and a lot of typing
console.log(A<string>('Hello'), A<number>(100));
// let the compiler do the work for us
console.log(A('Hello'), A(100))
如果您仅在一个位置使用泛型参数(即用于单个参数或用于返回值),则不会显示泛型的力量,而是在您使用它来指定两个或多个之间的关系时。
例如您的A
示例:
A('').bold() // ok return is the same as the parameter type
A1('').bold() //error return value is of type unknown
或者对于B
我们可以指定参数必须是同一类型
const B = <T>(t: T, u: T) =>
console.log(t);
console.log(u);
;
const B1 = (t: unknown, u: unknown) =>
console.log(t);
console.log(u);
;
B('Hello', 100); //compile time error
B1(100, 'Hello'); //compiles
泛型参数也可以对它们有额外的约束,因此并非所有类型都对给定的类型参数有效。
【讨论】:
非常感谢您提供的简明信息!。这很有帮助,我理解。 谢谢你们俩。我想了解未知和泛型之间的区别,这是完美的解释。以上是关于TypeScript 3.0 `unknown` 类型作为 `any` 或 `generics` 的替代品?的主要内容,如果未能解决你的问题,请参考以下文章