一、基础类型判断
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方法获取数组中的所有元素。