前言
使用管理员打开cmd,然后输入npm install -g typescript
慕课网免费课程:www.imooc.com/video/23202
typescript工具流
开发环境配置
2-2 main.ts
let hello = "hello world"
console.log(hello)
\
JavaScript工具流
npm init 安装配置
npm install --save-dev lite-server 安装对需要的文件 轻量级服务器lite-server
然后可以再终端直接输入npm satrt运行代码
浏览器检测到变化后自动进行变化
TS的基础类型
变量声明
尽量使用let
var会使得作用域混乱
// 课程3-1 变量声明
var number1 = 1;
let number2 = 2;
const number3 = 3;
function doSomething(){
// 使用var会使得变量i突破作用域
for(var i = 0;i < 5;i++){
console.log(i)
}
console.log(i)
}
doSomething();
‘
类型
- boolean
- string
- number
- array
- undefined
- object
新增的
- tuple
- enum
- void
- never
- any
高级类型
- union组合类型
- Nullable可空类型
- literal预定义类型
Number 数字类型
整数、浮点数、正负数
function add(n1:number,n2:number){
return n1+n2
}
// 如果不对变量进行限制的话,使用字符串也可以运行
console.log(add(number1,number2))
String字符串类型
"hello"、'hello'、`hello`
``反引号,可以创建一个字符串模板
let str = `我是$(firstName)`
Boolean布尔类型
真假
// 会进行自动指定,为布尔类型
let isTrue = true;
// isTrue = "false" 错误
// 也可以自己手动定义
let total:number = 0
let firstName:string = "你好呀"
let str = `我是$(firstName)`
数组Array
let list1:number[] = [1,2,3,4]
// 泛型
let list2:Array<number> = [1,2,3,4]
let list3 = [1,2,3,4]
let list4 = [1,"ddd"] //两种类型
let list5: any[] = [1,"dss",true]
元组 tuple
// Tuple 固定顺序
let people : [number,string] = [1,"ddd"]
// people[0] = "ddd" //出错 只能为数字类型
// people[1] = 1 //出错 只能为string类型
// people[2] = 2 //出错 不可以增加
// 元组固定长度,固定类型
// people.push(3) 没有出错,但是是错误,因为只能由两个不能够进行增加
// 联合类型
let people1 = [1,"ddd"]
联合类型 Union
就是同时标记两个属性,任选一个成立
let union : string | number
union = 2
union = "dddd"
//union = true //错误
let union2 : number | string | boolean | string[]
function add1(n1:number | string,n2 :number | string){
if(typeof n1 === "string" || typeof n2 === "string"){
return n1.toString() + n2.toString()
}else{
return n1 + n2
}
}
let addNumber = add1(1,3)
let addString = add1("123","3")
console.log(addNumber)
console.log(addString)
字面量类型 literal
// 字面量类型 literal
let union3: 0 | 1| 2
union3 = 1
// union3 = 4 //出错
let literal : 1 | "2" | true | [1,2,3,4]
function add1(
n1: number | string,
n2: number | string,
// 加上一个字面量类型
resultType:"as-number" | "as-string") {
if(resultType === "as-string"){
return n1.toString() + n2.toString();
}
if (typeof n1 === "string" || typeof n2 === "string") {
return n1.toString() + n2.toString();
} else {
return n1 + n2;
}
}
let addNumber = add1(1,3,"as-number");
let addString = add1(1,3,"as-string");
console.log(addNumber);
console.log(addString);
对变量的取值加上字面量类型,指定输出值
枚举 enum
枚举就是对变量赋予指定的值,默认按顺序赋值
// 枚举类型 Enum
enum Color {
red, // 0
green, // 1
blue // 2
}
let color = Color.blue
console.log(color) //2
enum Color2 {
red = 5,
green = 10,
blue = 1
}
enum Color3 {
red = "red",
green = "green",
blue = 1
}
any和unknow
any能够使得代码快速成型,unknow会更加准确一些,更加安全
// 3-7 any和unknown
// any代码
let randomValue: any = 666;
randomValue = true
randomValue = 1
randomValue = "true"
randomValue = {}
randomValue()
randomValue.toUpperCase() //不存在的,写出来没有报错,编译的时候出错
let randomValue: unknown = 666;
randomValue = true
randomValue = 1
randomValue = "true"
randomValue = {}
if (typeof randomValue === 'function'){
randomValue()
}
if (typeof randomValue === 'string'){
randomValue.toUpperCase()
}
void,undefined 和never
void是表示根本不存在
undefined表示还没有定义
never 表示永远无法完成
function printReasult():void {
console.log("hello-")
}
function printReasult1():undefined {
console.log("hello")
return
}
function throwError1(message:string,errCode:number):never {
throw {
message,
errCode
}
}
throwError1("not found",404)
function whileLoop():never {
while(true){
console.log(1)
}
}
whileLoop()
类型适配
- 变量前面加上,例如 message
- 变量后面加上类型,例如 message as string
注意每次使用的时候需要注意自己要转化的类型
// 3-9 类型适配(类型断言) Type Assertions
let message : any;
message = "abc" //虽然赋值是字符串,但是实际上还是any类型
// 使用括号和三角
let dd1 = (<string>message).endsWith("s")
// 使用as形式
let dd2 = (message as string).endsWith("s")
函数类型
- 给参数绑定类型
- 调用函数时候,需要对应数目和类型
- 给参数变量后加上?,表示可选参数
- 也可以直接给参数赋值
let log = function(message) {
console.log(message)
}
// 给参数绑定类型
// 调用函数时候,需要对应数目和类型
// 给参数变量后加上?,表示可选参数
// 也可以直接给参数赋值
let log1 = (message:string,age?:number) => {
console.log(age)
}
// log1("hello","123") //错误,因为第一个参数不是数字
log1("hello")
typescript面向对象
object对象类型
- 对象中不存在的变量会报错
- 如果不自己手动定义的话,对象内部的类型也会被自动定义好
const person = {
firstName : "ddd",
age:12
}
console.log(person.age)
// 对象中不存在的变量会报错
// 对象内部的类型也会被定义好
// key to type 键类型对
const person1:{
firstName:string,
age:number
} = {
firstName : "ddd",
age:12
}
Interface接口
之前对变量进行限制的时候,是有多种基础类型的,是可以通过定义类型的
```let drawPoint1 = (point:Point) => {`
console.log({x:point.x,y:point.y})
}
用Point来限制变量point
限制x和y的变量类型,限制x和y为number类型
interface Point{
x:number;
y:number
}
let drawPoint = (x,y) => {
console.log({x,y})
}
// 面向对象的方式,传入参数
let drawPoint1 = (point:Point) => {
console.log({x:point.x,y:point.y})
}
drawPoint1({x:122,y:12})
// drawPoint1({x:"122",y:"12"}) //出错 ,变量值的类型不匹配
// drawPoint1({weather:"干燥",temperature:"1oc"}) //出错,变量不匹配
// 对内部的变量加以限制
// 限制内部变量为两个,且都为number类型
// let getDistances = (a:PointerEvent,b:Point) =>{
// //
// }
interface Point{
x:number;
y:number
}
class类
类就是对对象的描述
- 公有属性
- 私有属性
- 传参
- 成员方法
- 私有成员方法
- 封装
- 继承
- 多态
使用interface来定义接口IPoint
其中有x、y、drawPoint、getDistances
interface IPoint{
x:number;
y:number,
// 用来描绘点数
drawPoint:()=>void;
// 用来计算两点间的距离
getDistances:(p:IPoint) => number;
}
接下来实现一个类
接口的实现接口 IPoint implements 实现
class Point implements IPoint {
x: number;
y: number;
drawPoint = () =>{
console.log("x: ",this.x," y: ",this.y);
}
// 计算距离
getDistances = (p:IPoint) => {
return Math.pow(p.x - this.x,2) + Math.pow(p.y-this.y,2)
}
}
// 高内聚低耦合
创建实例需要使用new, 对象实例化后就产生了对象
const point = new Point() //对象object,实例instance
// 对x和y进行初始化
point.x = 2;
point.y = 3
point.drawPoint()
使用构造函数constructor进行初始化,可以给变量名之后加上?这样子创建变量的时候,可以不给变量加上名字
javascript的构造函数不可以进行重载
x: number;
y: number;
constructor(x?:number,y:number = 2){
this.x = x;
this.y = y
}
使用访问修饰符,就会再构造变量的同时,函数会自动生成所需的成员变量
- public
- private
constructor(public x:number = 1,public y:number = 2){
}
\
Access Modifier访问修饰符
- public
- private
- protected
上面的构造函数可以改成:
constructor(private x:number = 1,public y:number = 2){
// this.x = x;
// this.y = y
}
使用getter和setter来对变量访问和赋值的时候进行限制
添加一个函数setX
setX = (value:number) => {
if(value < 0){
throw new Error("value 不能小于0")
}
this.x = value
}
可以建立一个内部和外部的缓冲带
point.setX(10)
point.setX(-10) //Error: value 不能小于0
建立一个getX函数
getX = () => {
return this.x
}
使用它自带的set,可以向定义一个变量一样
对x进行设置
set X(value: number){
if(value < 0){
throw new Error("value 不能小于0")
}
this.x = value
}
get X(){
return this.x
}
然后可以向属性一样进行访问和赋值
point.X = 12
console.log(point.X)
Module模块
将定义point的相关内容放入单独的一个ts文件中,
然后对其中的class前面加上一个export,
然后在前面的文件通过import {类名} from "文件地址"
import {Point} from "./point"
Generics泛型
- 使用类型+[]的方式来定义数组
- 使用泛型的类型来定义数组 Array<类型>
// 使用类型+[]的方式来定义数组
let list1: number[] = [1,2,3,4]
// 使用泛型的类型来定义数组 Array<类型>
let list2: Array<number> = [1,2,3,4]
定义一个泛型
let lastInArray = (arr:Array<number>) => {
return arr[arr.length - 1]
}
const l1 = lastInArray([1,2,3,4])
但是l1变为lastInArray(['1',"2","3"])
就会出错
这时候可以通过在函数前面加上<T>进行动态类型,例如let lastInArray = <T>(arr:Array<T>)
let lastInArray = <T>(arr:Array<T>) => {
return arr[arr.length - 1]
}
const l1 = lastInArray([1,2,3,4])
// 加上<string>指定类型
const l2 = lastInArray<string>(['1',"2","3"])
const l3 = lastInArray<string|number>(["a","b","c",1,2,3])
这时候的化,可以看到,语言会自动定义好类型,比如此时 l1的类型为number,l2的类型为string
可以在函数前面加上<T,Y>然后后面对应指定的类型,然后进行输出,就可以自己定义类型了
let makeTuple = <T,Y>(x:T,y:Y) => [x,y]
let makeTuple = <T,Y>(x:T,y:Y) => [x,y]
const v1 = makeTuple(1,"one")
const v2 = makeTuple<boolean,number>(true,1)