您的位置:

TS判断类型详解

一、基础类型判断

1、基础类型判断是TS最基本的功能。TS会在编译过程中对基础类型进行检查,该类型是否符合声明时的约定。

例如在声明一个字符串类型时:

const name: string = '张三';

在这个例子中,我们声明了一个字符串类型的变量name,并将其赋值为"张三"。TS将会在编译时对其进行检查,如果我们给它赋值为数字,就会报错。

2、当我们声明一个变量时,如果没有明确给它赋值,那么TS就会根据基础类型判断为undefined类型。例如:

let age: number;
console.log(age); // 输出undefined

在这个例子中,我们声明了一个数值类型的变量age,但是没有明确给它赋值,因此TS会将它判断为undefined类型。

3、我们可以使用typeof语句来获取变量的类型。例如:

const name: string = '张三';
console.log(typeof name); // 输出字符串类型string

在这个例子中,我们使用typeof语句来获取变量name的类型,获取结果是字符串类型string。

二、函数参数类型判断

1、在TS中,我们还可以对函数的参数类型进行判断。我们需要在函数声明时对其参数类型进行明确的声明。例如:

function add(num1: number, num2: number): number {
  return num1 + num2;
}

在这个例子中,我们声明了一个函数add,它有两个参数num1和num2,都是数值类型,并且它的返回值也是数值类型。

2、当我们在函数调用时,如果传入的参数类型与函数声明时不一致,就会报错。例如:

function printName(name: string): void {
  console.log(name);
}

printName(123); // 报错:类型“123”的参数不能赋给类型“string”的参数

在这个例子中,我们声明了一个函数printName,它的参数name是字符串类型,返回值是undefined类型。但是在调用函数时,我们传入的参数是数字类型,就会报错。

3、在函数参数中,我们还可以使用可选参数和默认参数。例如:

function printName(firstName: string, lastName?: string, age: number = 0): void {
  const fullName = lastName ? `${firstName} ${lastName}` : firstName;
  console.log(fullName, age);
}

printName('张', '三', 18);
printName('李', 22); // 输出:李 0

在这个例子中,我们声明了一个函数printName,它有三个参数。其中,第二个参数lastName是可选参数,第三个参数age是默认参数,默认为0。当我们调用函数时,如果不传入lastName,就会输出firstName和age的值,如果不传入age,就会输出firstName和默认的age值0。

三、类型守卫

1、类型守卫是TS中的一种语法,它用于在编程时对变量的类型进行判断。例如:

function printName(name: string | number): void {
  if (typeof name === 'string') {
    console.log(name.length);
  } else {
    console.log(name.toFixed(2));
  }
}

printName('张三'); // 输出3
printName(123.456); // 输出123.46

在这个例子中,我们声明了一个函数printName,它的参数name可以是字符串类型或数字类型。我们使用if语句对它们进行判断,并针对不同的类型执行不同的操作。

2、还有另外一种类型守卫语法,它使用TS中的is语法。例如:

interface Car {
  name: string;
  price: number;
}

interface Bike {
  name: string;
  type: string;
}

function isCar(vehicle: Car | Bike): vehicle is Car {
  return 'price' in vehicle; 
}

function getPrice(vehicle: Car | Bike): number | undefined {
  if (isCar(vehicle)) {
    return vehicle.price;
  }
}

console.log(getPrice({name: '奔驰', price: 500000})); // 输出500000

在这个例子中,我们声明了两个接口Car和Bike。然后我们定义了一个isCar函数,该函数判断传入的参数是否为Car类型,并返回布尔值。然后我们又定义了一个getPrice函数,它的参数类型是Car或Bike,返回值类型是数值类型或undefined。在函数内部,我们使用isCar函数对参数进行类型判断,如果是Car类型,返回参数的price属性值。

四、类型断言

1、类型断言是TS中一个非常有用的概念。通过类型断言,我们可以告诉TS编译器一个变量的类型,即强制将变量类型转换为我们所期望的类型。例如:

let str: any = 'hello world';
let len = (
   str).length;

console.log(len); // 输出11
   

在这个例子中,我们先声明了一个any类型的变量str,并赋值为字符串类型。然后我们使用类型断言来强制将其类型转为字符串类型。接下来我们又声明了一个变量len,将str的length属性赋值给它。

2、我们还可以使用另一种语法来进行类型断言,即使用as语法。例如:

let str: any = 'hello world';
let len = (str as string).length;

console.log(len); // 输出11

在这个例子中,我们使用as语法对变量str进行类型断言,将其转为字符串类型。然后我们又声明了一个变量len,将str的length属性赋值给它。

五、泛型类型判断

1、泛型是TS中一个非常重要的概念,它可以将类型参数化,从而使得函数或类可以适应不同的数据类型。在泛型函数或类中,TS可以根据传入的类型参数进行类型判断。

function identity
   (arg: T): T {
  return arg;
}

let str = identity
    ('hello world');
let num = identity
     (123);

console.log(typeof str, typeof num); // 输出string number
     
    
   

在这个例子中,我们声明了一个泛型函数identity,它有一个类型参数T,参数类型和返回值类型都是T类型。在函数的返回语句中,我们直接返回arg参数,这里arg的类型是T,所以返回值的类型也是T。当我们在调用函数时,需要明确给类型参数赋值,例如传入字符串类型和数字类型,输出它们的类型。

2、除了函数外,我们还可以在类中使用泛型。例如:

class Container
    {
  private data: T[] = [];

  add(item: T) {
    this.data.push(item);
  }

  remove(item: T) {
    this.data.splice(this.data.indexOf(item), 1);
  }

  getItems() {
    return this.data;
  }
}

let container = new Container
    ();
container.add('张三');
container.add('李四');
console.log(container.getItems()); // 输出['张三', '李四']
    
   

在这个例子中,我们声明了一个泛型类Container,它有一个类型参数T,成员变量data是一个T类型的数组。然后我们又声明了三个方法add、remove和getItems,它们的参数和返回值都是T类型。在调用这个类时,我们需要明确给类型参数赋值,例如传入字符串类型,调用add方法向数组中添加两个字符串,然后调用getItems方法获取数组中的所有元素。