TypeScript 3.0的“未知”类型可以替代“任何”或“泛型”?

时间:2018-07-28 08:35:41

标签: typescript generics

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的值只能分配给unknownany

     

例如,交换上面的示例以使用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类型版本{{1}中的unknown

2。 unknowngenerics之间的区别是什么?

例如,

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 个答案:

答案 0 :(得分:2)

关于您问题的第一部分,在大多数情况下,我可能会使用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

此外,通用参数可能对其具有额外的约束,因此并非所有类型都对给定类型参数有效。