TS-高级类型

1.交叉和联合类型

(1)交叉类型

格式: type1 & type2 & …
交叉类型是将多个类型合并为一个类型

	let mergeFn = <T, U>(arg1:T, arg2:U):(T & U)=>{
	    let res = {} as (T & U);
	    res = Object.assign(arg1, arg2);
	    return res;
	};
	let res = mergeFn({name:'lnj'}, {age:18});
	console.log(res);

(2)联合类型

格式: type1 | type2 | …
联合类型是多个类型中的任意一个类型

	let value: (string | number);
	value = 'abc';
	value = 123;

2.类型保护

对于联合类型的变量,在使用时如何确切告诉编译器它是哪一种类型。
通过类型断言或者类型保护。

	let getRandomValue = ():(string | number)=>{
	    let num = Math.random();
	    return (num >= 0.5) ? 'abc' : 123.123;
	}
	let value = getRandomValue();
	console.log(value);

虽然通过类型断言可以确切的告诉编译器当前的变量是什么类型,
但是每一次使用的时候都需要手动的告诉编译器, 这样比较麻烦, 冗余代码也比较多。

	let getRandomValue = ():(string | number)=>{
	    let num = Math.random();
	    return (num >= 0.5) ? 'abc' : 123.123;
	}
	let value = getRandomValue();
	if((value as string).length){
	    console.log((value as string).length);
	}else{
	    console.log((value as number).toFixed());
	}

定义了一个类型保护函数, 这个函数的’返回类型’是一个布尔类型。
这个函数的返回值类型是, 传入的参数 + is 具体类型。

	let getRandomValue = ():(string | number)=>{
	    let num = Math.random();
	    return (num >= 0.5) ? 'abc' : 123.123;
	}
	let value = getRandomValue();
	function isString(value:(string | number)): value is string {
	    return typeof value === 'string';
	}
	if(isString(value)){
	    console.log(value.length);
	}else{
	    console.log(value.toFixed());
	}

除了可以通过定义类型保护函数的方式来告诉编译器使用时联合类型的变量具体是什么类型以外,我们还可以使用typeof来实现类型保护
注意点:
如果使用typeof来实现类型保护, 那么只能使用 === / !==,只能保护 number/string/boolean/symbol类型。

	if(typeof value === 'string'){
	    console.log(value.length);
	}else{
	    console.log(value.toFixed());
	}

除了可以通过typeof类实现类型保护以外, 我们还可以通过instanceof来实现类型保护。

	class Person {
	    name:string = 'lnj';
	}
	class Animal {
	    age: number = 18;
	}
	let getRandomObject = ():(Person | Animal)=>{
	    let num = Math.random();
	    return (num >= 0.5) ? new Person() : new Animal();
	};
	let obj = getRandomObject();
	console.log(obj);
	if(obj instanceof Person){
	    console.log(obj.name);
	}else{
	    console.log(obj.age);
	}

3.Null和undefined

TypeScript具有两种特殊的类型, null和 undefined,它们分别具有值null和undefined。
默认情况下我们可以将 null和 undefined赋值给任意类型;null和 undefined也可以相互赋值;
注意点: 在企业开发中, 如果不想把 null和 undefined赋值给其它的类型;或者不想让 null和 undefined相互赋值, 那么我们就可以开启strictNullChecks。

	let value1:null;
	let value2:undefined;
	value1 = value2;
	value2 = value1;
	
	let value3:number;
	value3 = value1;
	value3 = value2;

如果我们开启了strictNullChecks, 还想把null和 undefined赋值给其它的类型。
那么我们就必须在声明的时候使用联合类型。

	let value:(number | null | undefined);
	value = null;
	value = undefined;

对于可选属性和可选参数而言, 如果开启了strictNullChecks, 那么默认情况下数据类型就是联合类型,就是当前的类型 + undefined类型。

	class Person {
	    name?:string
	}
	function say(age?:number) {
	
	}

去除 null或 undefined检测:

	function getLength(value:(string | null | undefined)) {
	    value = 'abc';
	    return ()=>{
	        // return value.length; // 报错
	        // return (value || '').length;
	        // return (value as string).length;
	        // 我们可以使用!来去除null和undefined
	        // !的含义就是这个变量一定不是null和undefined
	        return value!.length;
	    }
	}
	let fn = getLength('www.it66.com');
	let res = fn();
	console.log(res);

4.类型别名

(1)什么是类型别名

类型别名就是给一个类型起个新名字, 但是它们都代表同一个类型。
给string类型起了一个别名叫做MyString, 那么将来无论是MyString还是string都表示string

	type MyString = string;
	let value:MyString;
	value = 'abc';
	value = 123; //报错
	value = false;  //报错

(2)类型别名也可以使用泛型

	type MyType<T> = {x:T, y:T};
	let value:MyType<number>;
	value = {x:123, y:456};
	value = {x:'123', y:456};
	value = {x:false, y:456};

(3)可以在类型别名类型的属性中使用自己

	type MyType = {
	    name:string,
	    // 一般用于定义一些树状结构或者嵌套结构
	    children?:MyType
	}
	let value:MyType = {
	    name:'one',
	    children:{
	        name:'one',
	        children:{
	            name:'one',
	        }
	    }
	}

(4)接口和类型别名是相互兼容的

	type MyType = {
	    name:string
	}
	interface MyInterface {
	    name:string
	}
	let value1:MyType = {name:'lnj'};
	let value2:MyInterface = {name:'zs'};
	value1 = value2;
	value2 = value1;

5.类型别名和接口异同

(1)都可以描述属性或方法

	type MyType = {
	    name:string;
	    say():void;
	}
	interface MyInterface {
	    name:string;
	    say():void;
	}

(2)都允许拓展

	interface MyInterface {
	    name:string;
	    say():void;
	}
	interface MyInterface2 extends MyInterface{
	    age:number;
	}
	let value:MyInterface2 = {
	    name:'lnj',
	    age:18,
	    say():void{
	
	    }
	}
	type MyType = {
	    name:string;
	    say():void;
	}
	type MyType2 = MyType & {
	    age:number;
	}
	let value:MyType2 = {
	    name:'lnj',
	    age: 18,
	    say():void{
	
	    }
	}

(3)type 可以声明基本类型别名,联合类型,元组等类型, interface不能

	type MyType1 = boolean;
	type MyType2 = string | number;
	type MyType3 = [string, boolean, number];

(4)type不会自动合并

	interface MyInterface {
	    name:string
	}
	interface MyInterface {
	    age:number
	}
	let value:MyInterface  ={
	    name:'lnj',
	    age:18
	}
	
	type MyType = {  //报错
	    name:string
	}
	type MyType = {  //报错
	    age:number
	}

6.字面量类型

字面量就是源代码中一个固定的值
例如数值字面量: 1,2,3,… 例如字符串字面量: ‘a’,‘abc’,…
当使用字面量作为具体类型时, 该类型的取值就必须是该字面量的值。

	type MyNum = 1;
	let value1:MyNum = 1;
	let value2:MyNum = 2;  //报错,只能是1

7.可辨识联合

具有共同的可辨识特征。一个类型别名, 包含了具有共同的可辨识特征的类型的联合。

	interface Square {
	    kind: "square"; // 共同的可辨识特征
	    size: number;
	}
	interface Rectangle {
	    kind: "rectangle"; // 共同的可辨识特征
	    width: number;
	    height: number;
	}
	interface Circle {
	    kind: "circle"; // 共同的可辨识特征
	    radius: number;
	}

Shape就是一个可辨识联合
因为: 它的取值是一个联合,这个联合的每一个取值都有一个共同的可辨识特征

	type Shape = (Square | Rectangle | Circle);
	
	function aera(s: Shape) {
	    switch (s.kind) {
	        case "square": return s.size * s.size;
	        case "rectangle": return s.width * s.height;
	        case "circle": return  Math.PI * s.radius ** 2; // **是ES7中推出的幂运算符
	    }
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TSTypeScript)是一种静态类型检查的高级编程语言,它是JavaScript的超集。在TS中,基础类型和泛型都是其重要的概念。 基础类型指的是TS中预定义的简单数据类型,例如:number、string、boolean、null、undefined等。基础类型用于表示变量或函数的数据类型,可以直接赋值给变量,也可以用作函数的参数和返回值类型。基础类型的定义和使用非常简单,只需要在变量或函数的类型声明中指定即可。 泛型(Generic)是一种在编程中广泛使用的概念,它允许我们在定义函数、类或接口时使用可变的类型。使用泛型可以提高代码的复用性和灵活性。在TS中,使用<>符号来声明使用泛型,并通过类型参数来指定具体的类型。 例如,定义一个泛型函数: function identity<T>(arg: T): T { return arg; } 这个函数使用了泛型类型参数T,可以接受不同类型的实参,并返回相同类型的值。通过使用泛型,我们可以传入任意类型的参数,而不需要重写多个函数。 另外,在TS中还可以使用泛型约束来限制泛型类型的操作。通过在泛型类型参数后面添加extends关键字和约束类型,可以确保传入的类型必须满足特定条件。 总结起来,TS中的基础类型和泛型都是为了增强代码的可读性、可维护性和可靠性而设计的。基础类型用于定义简单的数据类型,而泛型则用于创建更灵活和可复用的函数、类和接口。在实际开发中,合理使用基础类型和泛型,可以提高代码的质量和开发效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值