方法调用unknown_TypeScript学习笔记(一)any和unknown

一. any类型

       TypeScript允许我们对 any 类型的值执行任何操作,而无需事先执行任何形式的检查。即逃离类型检查。

1.变量声明为any类型,则可以将任何类型的值付给变量,可以在赋值过程中改变类型

let color: any = 'red';
color = 0xF00 //OK

2.变量被声明为any类型,可以在变量上访问任何属性,调用任何方法,即使不存在,.ts编译成.js会通过

let anything: any = '新华路前端肖队';
anything.name = 'zhangyx20'; //OK

console.log(typeof anything); //string
console.log(anything.name); //undefined
console.log(anything.age); //undefined
console.log(anything.sayHello()); //js报错,anything.sayHello is not a function

       这样写greeter.ts编译成greeter.js不会报错,运行greeter.js,前三个不会报错,输出都是undefined,第四个会报错。

3.变量声明既没定义类型,也没赋值,则默认为any类型

let uncertain;
uncertain = '123'; //OK
uncertain = Number(uncertain); //OK

       注意:如果变量声明时赋了值,如let uncertain = 1;相当于let uncertain: number = 1;之后再更改类型编译会报错

二. unknown类型

       unknown和any和相似,TS中的所有类型均可以被归为any,也可以被归为unknown,即any和unknown都是TS的top type,区别在于any即时top type又是bottom type,而unknown只是top type。使用any类型,很容易会编写出编译正常但执行异常的代码,any不能默认保持安全。unknown解决了这一问题。

(一)

  1. 声明变量为unknown,则可以将任何类型的值付给变量,可以在赋值过程中改变类型。这一点和any是一样的

  2. unknown类型只能被赋值给any和unknown类型。
    先来看看any这么做会怎么样

let var1: any = 1;
let var2: string = var1; //OK,ts编译js通过,js运行也不报错
console.log(typeof var1) //number
console.log(typeof var2); //number

       再来试试unknown

cinst uncertain: unknown;

const var1: unknown = uncertain; //OK
const var2: any = uncertain; //OK
const var3: number = uncertain; //编译报错:error TS2322: Type 'unknown' is not assignable to type 'number'.
const var4: object = uncertain; //编译报错:error TS2322: Type 'unknown' is not assignable to type 'object'.
  1. 在声明为unknown的变量上访问属性和方法

let uncertain: unknown = 1;
uncertain.name = 'zhangyx20'; //error TS2339: Property 'name' does not exist on type 'unknown'.
console.log(uncertain.name); //error TS2339: Property 'name' does not exist on type 'unknown'.
  1. 对声明为unknown的值执行赋值外的其他操作

let var1: unknown = 1;
var1 = var1 + 1; //greeter.ts:76:8 - error TS2365: Operator '+' cannot be applied to types 'unknown' and '1'.

const var1: unknown = 'hello world';
console.log(typeof var1) //string
const var2: string = var1.slice(6) //greeter.ts:77:27 - error TS2339: Property 'slice' does not exist on type 'unknown'.

       实际上,对声明为unknown的值能够使用的运算符只有 ===,==,!==,!=这四个。

       经过以上四点的试探,我们可以擅作主张TypeScript 不允许我们对类型为 unknown 的值执行任意操作。这是个具有很强预防性的机制。我们在使用unknown类型的值之前,首先要执行类型检查,缩小值的类型范围

(二)使用类型收缩

1. 使用instanceof运算符获得更具体的类型。

const var1: unknown = 'hello world';
let var2: string;
if(typeof var1 === 'string'){
var2 = var1.slice(6) //OK,编译通过
}
console.log(var2) //world

2.使用instanceof运算符获得更具体的类型。

const var1: unknown = new String('hello world');
let var2: string;
if(var1 instanceof String){
var2 = var1.slice(6) //OK,编译通过
}
console.log(var2); //world

3.使用自定义保护函数,缩小 unknown 类型范围。

       下面这个例子声明了一个unknown类型的变量unknownValue,赋值为一个数组,现考虑将其所有元素转换为平方。可以自己写一个自定义保护函数,告诉TypeScript,我们知道自己在操作一个类型为unknown的变量。

const unknownValue: unknown = [1, 2, 3, 4, 5, 6];

//函数目的在于,告诉TypeScript,我们知道自己在操作一个类型为unknown,值为number-Array的变量
function isNumberArray(value: unknown): value is number[] {
return (
Array.isArray(value) &&
value.every(element => typeof element === "number")
);
}

if(isNumberArray(unknownValue)) {
unknownValue.map((value, index, self) => self[index] = value ** 2);
console.log(...unknownValue); //[2, 4, 9, 16, 25, 36]
}

2838e10f1b070b5f6262ba175d0b26fa.png

(三)使用类型断言

 通过类型断言,可以强制编译器信任类型为 unknown 的值为给定类型

const var1: unknown = 'Hello World';
console.log((var1 as string).toUpperCase()) //HELLO WORLD

const var2: unknown = 1;
//编译通过,转换为JS:var var2 = 1;console.log(var2.name);输出为undefined
console.log((var2 as { name: string }).name);

(四)联合类型

在联合类型中,unknown 类型会吸收任何类型,但是遇到any,会被吸收为any

type UnionType1 = string | unknown;       // unknown
type UnionType2 = unknown | any; //any

let var1: string = 1; //报错,因为var1是string类型
let var2: UnionType1 = 2; //编译通过,因为var2是unknown类型

(五)交叉类型

在交叉类型中,任何类型都可以吸收 unknown 类型

type IntersectionType1 = unknown & null;       // null
type IntersectionType2 = unknown & undefined; // undefined
type IntersectionType3 = unknown & string; // string
type IntersectionType4 = unknown & number[]; // number[]
type IntersectionType5 = unknown & any; // any

三. 什么时候用any,什么时候用unknown?

       any和unknown相比,unknown更安全,迫使我们对变量执行额外的类型检查,而使用any基本上是放弃了TS的所有类型检查。在大部分使用any和unknown的场景都是为了使用top type这一点。个人认为any不能滥用,如果一个变量的类型是固定的,但是现在还不确定或者不想确定,就将其声明为unknown类型,通过断言或类型收缩来正确使用它。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的。 TypeScript 中的 `any` 类型表示一个可以是任何类型的值。它可以用于避免类型检查,或者在你还没有确定类型的情况下使用。但是,使用 `any` 类型会放弃 TypeScript 带来的类型检查的所有优势,因此在能使用更精确类型的地方应尽量避免使用 `any`。 TypeScript 中的 `unknown` 类型表示一个未知的类型。它比 `any` 类型更加严格,因为在使用前需要进行类型检查。在某些情况下,你可能希望接收一个未知的值,但是又不想使用 `any` 类型,此时就可以使用 `unknown` 类型。 TypeScript 中的 `never` 类型表示永远不会有返回值的函数的返回值类型。它也可以表示永远不会被执行的代码块的类型。例如,当某个函数的所有可能执行路径都会抛出异常时,它的返回值类型就可以是 `never`。 希望这对你有所帮助。 ### 回答2: TypeScript中的`any`、`unknown`和`never`是三种特殊的类型。 1. `any`类型表示任何类型的值都可以赋值给它。它相当于取消了类型检查,可以在编写代码时快速推进开发,但也容易引入潜在的类型错误。使用`any`类型时需要慎重,最好在必要情况下使用,例如在需要与非TypeScript代码进行交互或在临时情况下。 2. `unknown`类型是TypeScript 3.0中引入的一种类型。与`any`相比,`unknown`类型提供了更加安全的动态类型。当我们不确定变量的类型时,可以使用`unknown`类型来保持类型的不确定性。在使用`unknown`类型的值时,我们必须首先进行类型检查或类型断言,以将其转换为更具体的类型。与`any`不同,`unknown`类型不会自动允许我们执行任意操作。这种类型的引入提高了代码的类型安全性,减少了潜在的类型错误。 3. `never`类型表示它永远不会发生的类型,即表示从不返回值的函数的返回类型以及永远无法完成的操作的结果类型。例如,在一个函数中抛出了异常,或者存在无限循环。使用`never`类型可以更好地定义某些情况下的函数或操作的返回类型,同时帮助我们避免潜在的逻辑错误。 ### 回答3: TypeScript是一种静态类型的编程语言,它可以在JavaScript的基础上添加静态类型检查和一些其他特性。在TypeScript中有三种特殊的类型:any、unknown和never。 any类型表示任意类型,它可以用来表示任何类型的值。使用any类型可以绕开类型检查,编译器不会对any类型的值进行类型检查和推断。any类型的变量可以接受任何类型的值,因此在使用any类型时需要特别小心,因为它可能导致类型错误和运行时错误。 unknown类型也表示任意类型,但它比any类型更严格。当使用unknown类型时,编译器会要求进行类型检查和类型断言,以确保类型安全。unknown类型的变量不能直接赋值给其他类型的变量,必须经过类型断言或类型检查后才能进行赋值。这种类型更适合在编写通用代码或处理动态类型的情况下使用,相比any类型,unknown类型提供了更加严格的类型安全。 never类型表示永远不会发生的类型。它通常会用在函数的返回类型中,表示该函数永远不会正常返回。例如,一个会抛出异常或进入无限循环的函数的返回类型可以设为never。同时,never类型也可以用来处理不可到达的代码块,例如一个带有无限循环的函数的后续代码块。 总而言之,在TypeScript中,any类型和unknown类型都表示任意类型,但unknown类型更加严格,并且要求进行类型检查和类型断言。而never类型表示永远不会发生的类型,通常用于函数的返回类型或不可到达的代码块。使用这些类型要谨慎,并且根据实际需求来选择合适的类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值