关于 TypeScript 的一些学习笔记

·  阅读 43

安装 TS

安装

npm install -g typescript

检查版本,有没有安装成功

tsc -V

TS 基础知识

接口(interface):是一种能力,一种约束而已

  • 看例子
(()=>{
    //定义一个接口
    interface IPerson{
        firstName: string //姓氏
        lastName: string //名字
    }
    //输出姓名
    //给person 加上IPerson 之后,下方写的 firstName 那些会自动提示
    function showFullName(person: IPerson){
        return person.firstName + person.lastName
    }
    //定义一个对象
    cosnt person = {
        firstName:'东方'
        lastName:'不败'
    }
    //因为定义的对象符合一开始定义的接口,所以ts不会报错
    console.log(showFullName(person))
})()
复制代码

类(TS 里的类只是个语法糖,本质上还是 JS 函数的实现)

  • 看例子
(()=>{
    //定义一个接口
    interface IPerson{
        firstName: string //姓氏
        lastName: string //名字
    }
    // 定义一个类型
    class Person {
        //定义公共的字段(属性)
        firstName: string //姓氏
        lastName: string //名字
        fullName: string //姓名
        //定义一个构造器函数
        constructor(fisrtName:string, lastName:string){
            //更新属性数据
            this.firstName = firstName
            this.lastName = lastName
            //姓名
            this.fullName = this.firstName + this.lastName
        }
    }
    //定义一个函数
    function showFullName(person: IPerson){
        return person.firstName+person.lastName
    }
    //实例化对象
    const person = new Person('诸葛','孔明')
    console.log(showFullName(person))
})()
复制代码

提示

npm init -y 该命令可以产生一个 package.json

tsc --init 该命令可以产生对应的 tsconfig.json

TS 常用语法

基础类型

  • TS 支持与 JS 几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用。

布尔值

  • 最基本的数据类型,在 JS 和 TS 里叫 boolean
let isDone: boolean = false;
isDone = true
// isDone = 2 // error
复制代码

数字

  • 和 JS 一样,所有数字都是浮点数,类型是 number,除了支持十进制和十六进制字面量,TS还支持 ES2015 引入的二进制和八进制字面量
let a1: number = 10 //十进制
let a2: number = 0b1010 // 二进制
let a3: number = 0o12 //八进制
let a4: number = 0xa //十六进制
复制代码

字符串

  • 和 JS 一样,可以用""''表示字符串
let name: string = 'tom'
name = 'jack'
// name = 12 //error
let age: number = 12
const info = `My name is &{name},I am ${age} years old`
复制代码

null 和 undefined

  • TypeScript 里,undefinednull 两者各自有自己的类型分别叫做 undefinednull。 它们的本身的类型用处不是很大,可以作为其他类型的子类型
let u: undefined = undefined
let n : null = null
// 子类型,注意在严格模式下会报错
let num2: number = undefined
let num3: number = null
复制代码

数组类型

// arr1 的类型是一个数字数组
//语法:let 变量名:数据类型[] = [值1,值2]
let arr1: number[] = [1,2,3]
//数组定义方式2:泛型的写法
//语法: let 变量名:Array<数组类型> = [值1,值2]
let brr2:Array<number> = [1,2,3]
复制代码

元组类型

//定义数组的时候,类型和数据的个数就已经限定了
//注意元组类型在使用的时候,数据的类型和位置和个数,应该和在定义元组的时候位置数量一致
let arr1:[string, number, boolean] = ['小甜甜', 100, true]
复制代码

枚举类型

  • enum类型是对 JS 标注数据类型的一个补充,使用枚举类型可以为一组数值赋予友好的名字
//枚举类型,枚举里面的每个数据值都可以叫元素,每个元素都有自己的编号,从0开始依次递增加1
enum Color {
    red,
    green,
    blue
}
//定义一个 Color 的枚举类型的变量来接收枚举的值
let color:Color = Color.red
console.log(color) // 0
console.log(Color.red, Color.green, Color.blue) // 0,1,2
//也可以通过值来拿到对应的元素
console.log(Color[3]) // blue

复制代码

any 类型

  • 有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用 any 类型来标记这些变量:
let notSure: any = 4
notSure = 'maybe a string' //可以是个字符串
notSure = false // 也可以是个 boolean
复制代码
  • 或者一个数组,它包含了不同类型的数据,你只知道部分类型
let list: any[] = [1, true, 'free']
list[1] = 100
复制代码

void 类型

  • 某种程度上来说,void 类型像是与 any 类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void
/* 表示没有任何类型, 一般用来说明函数的返回值不能是undefined和null之外的值 */
function fn(): void {
  console.log('fn()')
  // return undefined
  // return null
  // return 1 // error
}
复制代码
  • 声明一个 void 类型的变量没有什么大用,因为你只能为它赋予 undefinednull
let unusable: void = undefined
复制代码

object 类型

  • object 表示非原始类型,也就是除 numberstringboolean之外的类型。

    使用 object 类型,就可以更好的表示像 Object.create 这样的 API

  • 例如:

// 定义一个函数,参数是 object 类型,返回值也是 object 类型
function fn2(obj:object):object {
  console.log('fn2()', obj)
  return {}
  // return undefined
  // return null
}
console.log(fn2(new String('abc')))
// console.log(fn2('abc') // error
console.log(fn2(String))
复制代码

联合类型(Union Types)

  • 联合类型(Union Types)表示取值可以为多种类型中的一种
  • 需求1: 定义一个一个函数得到一个数字或字符串值的字符串形式值
// 接收的参数可以是数字类型可以是字符串类型,返回值是 string
function getString(str:number | string): string{
    return str.toString()
}
console.log(getString('123')) //正常输出
console.log(getString(123)) //正常输出
复制代码
  • 需求2: 定义一个一个函数得到一个数字或字符串值的长度
//返回长度,所以返回值类型为 number
function getString(str:number | string):number{
    return str.toString().length
}
console.log(getString('123')) // 3 //正常输出
console.log(getString(123)) // 3 //正常输出
复制代码

类型断言

  • 通过类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。 TypeScript 会假设你,程序员,已经进行了必须的检查。

    类型断言有两种形式。 其一是“尖括号”语法, 另一个为 as 语法

/* 
类型断言(Type Assertion): 可以用来手动指定一个值的类型
语法:
    方式一: <类型>值
    方式二: 值 as 类型  tsx 中只能用这种方式
*/

/* 需求: 定义一个函数得到一个字符串或者数值数据的长度 */
function getLength(x: number | string) {
    //类型断言,方式一
    //指定参数 x 类型是 string
  if ((<string>x).length) {
     // 类型断言,方式二
    return (x as string).length
  } else {
    return x.toString().length
  }
}
console.log(getLength('abcd'), getLength(1234))
复制代码

类型推断

  • 类型推断: TS会在没有明确的指定类型的时候推测出一个类型
  • 有下面2种情况:
      1. 定义变量时赋值了, 推断为对应的类型
      2. 定义变量时没有赋值, 推断为 any 类型
/* 定义变量时赋值了, 推断为对应的类型 */
let b9 = 123 // 此时 b9 类型推断为 number
// b9 = 'abc' // error

/* 定义变量时没有赋值, 推断为any类型 */
let b10  // 此时 b10 类型推断为 any
b10 = 123
b10 = 'abc'
复制代码

接口

  • TypeScript 的核心原则之一是对值所具有的结构进行类型检查。我们使用接口(Interfaces)来定义对象的类型。接口是对象的状态(属性)和行为(方法)的抽象(描述)

  • 接口:是一种类型,是一种规范,是一种规则,是一个能力,是一种约束

需求:创建人的对象, 需要对人的属性进行一定的约束

id 是 number 类型, 必须有, 只读的
name 是 string 类型, 必须有
age 是 number 类型, 必须有
sex 是 string 类型, 可以没有
复制代码

示例:

可选属性、只读属性

//定义一个接口,该接口作为 person 对象的类型使用,限定或是约束该对象中的属性数据
interface IPerson {
    
}
//定义一个对象,该对象的类型就是我定义的接口 IPerson
const person:IPerson = {
    id:1,
    name:'小甜甜',
    age:18
    sex:'女'
}
复制代码

下面通过一个简单示例来观察接口是如何工作的:

/* 
在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型
接口: 是对象的状态(属性)和行为(方法)的抽象(描述)
接口类型的对象
    多了或者少了属性是不允许的
    可选属性: ?
    只读属性: readonly
*/

/* 
需求: 创建人的对象, 需要对人的属性进行一定的约束
  id是number类型, 必须有, 只读的
  name是string类型, 必须有
  age是number类型, 必须有
  sex是string类型, 可以没有
*/

// 定义人的接口
interface IPerson {
  // 加上 readonly 表示 id 是只读的  
  readonly id: number
  name: string
  age: number
  // 冒号前加上 ? ,表示这个属性可以没有
  sex?: string
}

const person1: IPerson = {
  id: 1,
  name: 'tom',
  age: 20,
  sex: '男'
}

// person1.id = 2 // 错误,因为是只读的
// 把 person1 中的 sex 去掉,不会报错,因为这个属性可有可无
复制代码

函数类型

  • 函数类型: 通过接口的方式作为函数的类型来使用
  • 为了使用接口表示函数类型,我们需要给接口定义一个调用签名。
  • 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。
(()=>{
    // 定义一个接口,用来作为某个函数的类型使用
	interface ISearchFunc {
    	//定义一个调用签名,在括号里写上函数的参数,外面写上函数的返回值类型
    	(source:string,subString:string):boolean
	}
	// 定义一个函数,该类型就是上面定义的接口,函数参数就是上面的调用签名
	const searchString: ISearchFunc = function (source:string,subString:string):boolean {
        //在 source 字符串中查找 subString 这个字符串
    	return source.search(subString) > -1
	}
	// 调用函数测试
	console.log(searchString('你好呀','呀')) // true //因为 “呀” 存在于 “你好呀”
})()
复制代码

未完待续...

分类:
前端
标签:
分类:
前端
标签: