TypeScript常用基础语法学习

ts的安装

npm install -g typescript       //全局安装

安装完成后控制台 输入 ==tsc -v === 有以下输出说明安装成
在这里插入图片描述

基础类型写法

let numb: number = 123   //数字类型
let myStr: string = '123456'  //string 类型
let myBl: boolean = true  //布尔类型
let u: undefined = undefined //undefined
let n: null = null  //undefined

//  undefined 和 null   是任意类型的子类 , 所以下面写法不会报错
let num: number = undefined

// any 类型
// any 类型就是任意类型都可以,这个就失去了对类型的约束,跟js一样了,建议不使用
let isAny: any = '123' 
isAny = 123
isAny.nub = null 

字面量

//字面量 |:  
let a: '你好' | '你也好'   //a的值如果不是其中的一个就会报错
a = '你好'
a = '你也好'

unknown类型


//unknown类型跟any类型非常的像,但是unknown类型必须要经过验证才能使用,二 any类型数据不需要

let score: unknown = 5
// 这个时候会报错
console.log(score * 2);

// 那我们要验证 一下类型 就能使用 unknown类型的数据了
if (typeof score === 'number') {
    console.log(score * 2)    
}

数组


let arr: number[] = [1, 2, 3,]   //数字类型的数组,知道是数字 不能是其他

let arrs: Array<string> = ['1', '3', '哈哈哈']  //这样写法也可以

二维数组

let arr2: number[][] = [[1, 3, 4, 5, 6]]

对象类型数组

//  对象类型的数组
let objArr: { name: string, age: number }[] = [{ name: '张三', age: 24 }]

往数组中push不同类型数组也是会报错

// 往数组里面push不同类型的数据 也是会报错的
let num: number[] = [1, 3, 4, 5, 6]
num.push('你好')  //error  报错

数组也可以是any类型

// 数组也可以是any类型
let anyArr: any[] = [1, 3, 'hello', { name: '李四', age: 35 }]

对象


// 对象
// 属性后面加?表示可选参数,可以加可以不加
let obj:{name:string,age:number,address?:string}

// 写了address也对
obj = { name: '李雷', age: 23, address: '中国' }  

// 不写 address也可以,
obj = { name: '李雷', age: 23 }

// 如果我希望 一个对象里必须要有 name属性,其他的可有可无

//proName是形参 可以传任意,类型必须是自己定义的类型

let a: { name: string, [proName: string]: any }

a={name:'lili'}

a = { name: 'hah', address: '中国',height:178 }

函数

// 函数
/* 
    函数的可选参数也是参数后面加 ? 号
    可以参数后面不能再跟参数
*/
//第一种写法
function add(x:number,y:number,z?:number):number {
    return x+y
}
//传3个参数
add(1, 2, 3)
add(1,2) //传两个参数

第二种写法

// 第二种写法
let merge: (x: number, y: number, z?: number) => number = function (x: number, y: number, z?: number): number{
    return x+y
}

第三种箭头函数写法

// 换成箭头函数的写法
let add2: (x: number, y: number, z?: number) => number = (x: number, y: number, z?: number): number => {
    return x+y
}

推荐写法

// 推荐这个写法,比较简便点
function fun(x: number, y: number): number{
    return x + y
}

函数的各种返回值写法

// 如果函数没有返回值就是 void
function fn(x: number, y: number): void{
    console.log(x+y)   
}
// 如果是没有返回值的函数加了返回值就会报错

// 函数返回的是数组

function fnArr(x: number, y: number): number[]{
    return [x,123]
}
// 函数返回的是对象

function fnObj(x: number, y: number): { age: number }{
    return { age: x } 
}

// 返回值是函数
function _fn(a: number): (b: number) => number{
    return function (b: number) {
        return a + b
    }
}

类型别名

// 类型别名
type a = number
let b: a = 123456

// 类型别名定义函数
type add = (x: number) => number
let add2: add = (x: number): number => x

function fn(x: string, y: number): boolean {
	return false
}

let fn2:(x: number)=> string = function(x: number) : string{ 
    return 'hah'
}

联合类型

// 联合类型

// 联合类型使用 | 分割每个类型

// 联合类型中 函数必须要用括号包起来

let fc: number | string | boolean | ((x: number) => number) | string[]

//  这样 fc可以是上面定义的其中一种
fc = false
fc = 'hello'
fc = ['h', 'e', 'l', 'l']
fc = function (x: number) {
	//函数类型
	return x
}
fc(5) //调用

/*所以我们之前定义存储不同数据数组的时候,也可以使
用联合类型
*/
const arr: (number | string)[] = [1, 'string', 2, 'true']

/**
特殊的,如果访问联合类型的属性或方法:
当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时
候
我们只能访问此联合类型的所有类型里共有的属性或方法:
 */

function getLength(sem: string | number): number {
	return sem.length //这里就会报错,因为 length不是string和number共有的属性
}

function getstr(sem: string | number): string {
	return sem.toString()  //这样访问是正确的,toString()是他们共有的属性
}

接口 interface

在typescript中我们可以使用 接口(interface)来定义对象

**接口其实就是用来定义一个模板,以后 声明的对象 都要按照这个模板来定义**
// 接口

interface girl {
	height: number
	like: boolean
	money?: number //可选属性
	readonly age: number //只读属性,如果修改只读属性就会报错
}

interface person {
	name: string
	money: number
	like: boolean
	hobby: string[]
	make: () => void //函数无返回值
	girlFriend: girl //对象 要与 接口girl一样
}
// 实现接口

let zs: person = {
	name: '张三',
	money: 100,
	like: true,
	hobby: ['唱歌', '跳舞'],
	make: () => {},
	girlFriend: {
		height: 165,
		like: true,
		money: 1000,
		age: 18,
	},
}

console.log(zs)

zs.girlFriend.age = 28  //更改只读属性会报错

有时候我们需要一个接口有任意属性 我们要这么写

interface person{
	name: string,
	age?: number,
	[propName:string]:any,  //任意属性定义	
}

// 实例
let tom: person = {
	name: 'tom',
	age: 25,
	gender:'male'
}

需要注意的是,一旦定义了任意属性,那么确定属性和
可选属性的类型都必须是它的类型的子集:

一个接口中只能定义一个任意属性。如果接口中有多个
类型的属性,则可以在任意属性中使用联合类型

interface Person{
	name: string,
	//age?:number,  //注意使用了任意属性以后,如果任意属性不是any类型,可选属性就会报错
	[propName:string]:number|string,  //任意属性定义	
}

// 实例
let tom: Person = {
	name: 'tom',
	age: 15,
	gender: "男",
	height:180
}

接口的继承

// 接口的继承
interface Person{
	name: string,
	age:number
}
// 接口继承,要完全继承Person是属性
interface BoyFriend extends Person{
	money: number,
	hobby:string[]
}
// 创建对象的时候必须要把继承的属性也要创建
let xm: BoyFriend = {
	name: 'xm',
	age: 34,
	money: 2000,
	hobby:['cg','tw']
}

一个接口可以被多个接口继承,同样,一个接口也可以
继承多个接口,多个接口用逗号隔开

// 多个接口的继承
interface Animals{
	name:string
}
interface Friends{
	like:string
}
// 继承多个接口,用逗号分开
interface Dog extends Animals, Friends{
	name: string,
	color:string
}

const dog: Dog = {
	name: '狗',
	like: 'sleep',
	color:'黄色'
}

接口中使用联合类型


// 接口中也可以使用联合类型

interface Person{
	name: string,
	like: string | string[] | (() => string)
}

// 接口使用联合类型实现
let xm: Person = {
	name: 'xm',
	// like: '足球',
	// like: ['篮球,足球'],
	like: () => '就是玩'
}

接口定义数组

// 接口定义数组
interface arr{
	// 这里[] 内是数组的下表索引,必须要是number类型
	[index:number]:string
}
// 实现
let arrList: arr = ['1', '3', '4']

类型断言

类型断言就是我明确的知道我这个数据肯定是字符串,
告诉编译器你不用检测他了。

语法

值 as 类型

联合类型用途

1.将一个联合类型断言为其中一个类型

**当 TypeScript 不确定一个联合类型的变量到底是哪个类
型的时候,我们只能访问此联合类型的所有类型中共有
的属性或方法
**

// 类型断言

interface Cat{
	name: string,
	run():void
}
interface Fist{
	name: string,
	swin():void
}

function getName(animal: Cat | Fist) {
	return animal.name  //只能访问共有属性
}

function getAs(animal: Cat | Fist) {
	// 使用断言 把 animal断言成 Fist就能使用它的 函数方法

	if (typeof (animal as Fist).swin === "function") {
		//这样子 animal.swin 就不会报错了
		return true   
	} else {
		
		return false
	}
}

需要注意的是,类型断言只能够「欺骗」TypeScript 编
译器,无法避免运行时的错误,反而滥用类型断言可能
会导致运行时错误:

使用类型断言覆盖其类型推断


/**
 案例  
   使用类型断言(as关键字) 来覆盖其类型推断
 */

let student = {}
//  let  student:{}

student.name = "jack"   //报错  类型“{}”上不存在属性“name”


// 使用类型断言 as 来覆盖, 这个时候就需要有一个接口

interface Person{
	name:string
}

let sdt = {} as Person

sdt.name = "sdt"  //这样就不会报错

将父类断言成子类
// 将父类断言成子类

class Student{
	make() {
		console.log('i can like money')
		
	}
}
class xm extends Student {
	run() {
		console.log('i can run')
		
	}
}

let a = new Student();

a.run()  // 类型“Student”上不存在属性“run”

(a as xm).run()  // 断言成子类,正确

非空断言
let num: number | undefined | null

// 在num后面添加非空断言符 ! ,以此来断言num是非空值
num!.toFixed()


// 这种写法的意思是,如果num不为空就执行 toFixed()这个方法
num?.toFixed()

和其他类型断言一样, 这种断言只会让TypeScript不报错, 但不会
改变代码运行时的行为
简单说就是在编译后运行时如果num变量的值是null 或
undefined ,JavaScript依然会报错

元祖(可以存放多种类似的数组)

**我们知道数组中元素的数据类型都一般是相同的(any[] 类型的
数组可以不同)
如果存储的元素数据类型不同,则需要使用元组。
元组中允许存储不同类型的元素,元组可以作为参数传递给函
数。元祖的数量是固定的
**


let arr: [string, number] = ['18829', 124];

// const arr1: [number, string] = ['sein', 2334]  //error 这个时候数组值的位置类型对不上就报错

// 当添加越界元素的时候,元祖的类型会被限制为元祖中每个类型的联合类型

arr.push(123)
arr.push('hahah')
arr.push(true)   //这里就报错了,不是元祖中定义的两个类型

枚举

// 枚举

enum Arr {
	one=1,two,three,foru
}


// 如果没指定 one=1 的时候 默认是从 0 开始,后面自动递增
console.log(Arr.one === 1); //true
console.log(Arr.three === 3); //true

// 它们的值是可以反向映射的
console.log(Arr['two'] === 2);  //true


// 可以收到给赋值

enum xm { a = 1, b, c, d = 8, e }

// 未手动赋值的枚举项会接着上一个枚举项递增。
console.log(xm.a === 1);//true
console.log(xm.b === 2);//true

泛型

泛型(Generics)是指在定义函数、接口或类的时候,
不预先指定具体的类型,而在使用的时候再指定类型的
一种特性。

有时候我们想函数传入的值跟返回的值是同类型,那么我们就需要使用泛型来精减代码量

// 函数中使用泛型

function indentity<T>(arg:T): T{
	
	return arg
}
indentity(500) //正确

我们给identity添加了类型变量T。 T帮助我们捕获用户
传入的类型(比如:number),之后我们就可以使用
这个类型。 之后我们再次使用了 T当做返回值类型。现
在我们可以知道参数类型与返回值类型是相同的了。 这
允许我们跟踪函数里使用的类型的信息。
我们把这个版本的identity函数叫做泛型,因为它可以适
用于多个类型。 不同于使用 any,它不会丢失信息,像
第一个例子那像保持准确性,传入数值类型并返回数值
类型。

对象接口中使用泛型

// 对象接口中使用泛型

interface Person<T>{
	name: string,
	age:T
}
const xiong: Person<string> = {
	name: 'xiong',
	age: '28',
	// age:28   // 报错	
}

class 类


// class 类
class Person{
	name: string
	age: number
	constructor(name:string,age:number) {
		this.name = name
		this.age=age
	}
	sleep() {
		console.log('我睡一会觉')
	}
}
const xiong = new Person('xiong', 18)
console.log(xiong);

// 继承
class long extends Person{
	hobby: string[]
	sex:string
	constructor(name: string, age: number, sex: string) {
		// 子类的构造器必须主动调用父类的构造器super(),这样才能继承
		super(name, age)
		this.sex = sex
	}
	sleep(): void {//重写,子类的方法如果跟父类一样,就会吧父类的覆盖
		console.log('我好困')	
	}
}

访问修饰符

public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的

private 修饰的属性或方法是私有的,不能在声明它的类的外部访问

protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的

class Animal{
	public name: string
	private age: number    //private 私有的不能在申明它的类的外部访问
	protected color:string  //protected修饰是可以被子类中访问,但是还是不能在外部访问
	public constructor(name:string,age:number,color:string) {  //public是可以被访问的
		this.name = name
		this.age = age
		this.color=color
	}
}
const dog = new Animal('狗', 2,'黄色')
//console.log(dog.age) //这里访问私有属性,已经报错了,子类中也是不能访问的

抽象类(abstract)

抽象类是不允许被实例化的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值