学习ts类型

ts

typescript是拥有类型的javaScript超集, 它可以编译成普通\干净\完整的js代码 ,始于js,终于js,

安装
npm install -g typescript
tsc 文件名 //将ts文件编译成为js文件。

vsCode自动编译ts
// 1.新建个index.ts文件
// 2.终端执行 tsc --init  会在自动生成tsconfig.json文件  修改这个文件outDir为  "outDir": "./js",
// 3.Vs Code  打开终端 ->运行任务 -> typescript ->"tsc: 监视 - tsconfig.json (ts"
命令行启动
	npm install node-ts -g   // 安装node-ts
	node-ts '文件名' // 使用方法

数据类型

number

包含NaN ,二进制,十进制,八进制等数字

let num: number = 123;
num = 100;```
booleab

布尔值 只有 true 、false 两个值

let flag: boolean = true;
flag = false;
flag = 1 > 0;
string
let msg: string = "hello world";
null和undefined

js中null和undefined是两个基本数据类型
在ts中 null和undefined他们是类型 也是值

var n = null;
var u = undefined;
n = null;
n = undefined;
symbol

表示唯一值

// @ts-ignore
let sym1: symbol = Symbol("name");
// @ts-ignore
let sym2: symbol = Symbol("name");
const obj = {
    [sym1]: "hello world",
    [sym2]: "你好世界",
}
数组

在数组中最好放相同数据类型的内容

    let arr: number[] = [] // 写法1
    let arr1: Array<string> = [] // 写法二 jsx中尽量不要使用这个方式
object
const obj = {
    name: "你好世界",
    age: 18
}

any

any类型表示任意类型

let msg: any = "1234";
msg = 123;
msg = true;
msg = [];
msg = null;
unknow

unknown类型 只能赋值给any和unknown类型的变量


let flag:boolean = true;
let res: unknown='你好世界';
// let msg: any = res //ok
let msg: unknown = res // ok
flag=res // 报错 不能将类型“unknown”分配给类型“boolean”
void

当前方法没有返回值

never

通常用来声明永远不会正常返回的函数的返回值类型

    function fn(): never {
        throw new Error('never类型')
    }

元组 Tuple

已知元素数量和类型的数组,各元素的类型不必相同

 let tup: [number, string] = [1, '1']
 // 如果不确定可以使用? 只能放在最后以为使用
 let tup: [number, string?] = [1]
enum

enum 声明的都是常量

 // 数字枚举
 // enum Color {Red, Green, Blue} Red:0  Green:1  Blue:2
 // enum Color {Red, Green=100, Blue} Red:0  Green:100  Blue:101
 enum Color { Red, Green = 100, Blue }
 let c: Color = Color.Blue // 101
 // 字符串枚举
 // 在字符串枚举里,每个成员都必须用字符串字面量进行初始化。
 enum Direction {    Up = "UP", Down = "DOWN",  Left = "LEFT",   Right = "RIGHT",    }
 let up:Direction=Direction.Up
 console.log(up);
 // 混合枚举
 //只有第一位可以不用定义
 enum blend{
    empty,
    num=1,
    str='1'
}

补充数据类型

联合类型
    type union=string | number
    let num:union='123'
    let num1:union=123  
可选类型 ?
类型别名
	type newNumber=number
类型断言

ts无法获取具体的类型信息(HTMLElement),但是这些(HTMLImageElement)信息有又独特的属性和方法,此时就需要告诉ts当前的这个数据类型到底是那种
// TS只允许类型断言转换为 更具体 或者 不太具体(any/unKnown) 的类型版本. 这种情况会导致ts类型混乱

        let num = <number>1  //<>写法
        let str = '1' as string  // as写法
        //HTMLElement as HTMLImageElement
       let img = document.getElementById("img") as HTMLImageElement
       let str: string = "你好世界";
       let num: number = str as unknown as number
?? == || , !!==Boolean()
字面量类型
//ts中字面量类型
let str: "你好世界" = "你好世界"
类型缩小==>类型保护
//typeof
//instanceof
//常见的比较 (== === != !==)  switch
//in  in 用于确定对象是否具有带名称的属性
//is  is类型谓词 判断一个变量是否为该类型
    //  keyof 返回接口中的所有key值 并生成联合类型 

函数

let fn:Function=function(){} //声明函数第一种方式
let fn1:()=>void=()=>{} //声明函数第二种方式
//函数能够通过传递参数的类型自动推导返回值的类型
//ts中使用 arguments 会报错 可以使用...展开运算符获取
// 当函数在外部时需要在函数中定义一个形参 this ,函数体内才能正常使用this
//函数重载
//通过函数签名的形式来实现函数重载
function sum(a1:number, a2:number): number;
function sum(a1:string, a2:string): string;
function sum(a1: any, a2: any){
    return a1+a2
}
//在调用函数的时候,它会根据我们传入的参数类型,来对函数签名一个一个对比,哪怕数据类型是any只要不符合任意一个重载函数签名,那么都是不能使用的来决定执行函数时,到底执行哪一个函数签名
sum(1,2);//3
sum("1","2");//"12"

泛型

定义一个方法或者接口的时候,不确定用户传递什么类型的参数回来 那么也就不能确定返回值,需要使用者来进行传递

     // 传入什么类型返回什么类型
    function fn<t, f>(a: t, b: f): void {
    }
    fn<string, number>('1', 2) //传值的时候固定参数类型 或者不固定参数类型  fn('1', 2)
    interface Lengthwise {
        length: number;
    }

    // 泛型约束
    function loggingIdentity<T extends Lengthwise>(arg: T): T {
        console.log(arg.length);  // 5
        return arg;
    }
    loggingIdentity('11') // 此时函数默认推导出字面量类型:11
	//约定俗成的开发过程中一些常见名称
	//T: type的缩写, 类型
	//K/V: key和value的缩写, 键值对
	//E: element的缩写, 元素
	//O: object的缩写, 对象
    function isNumber(x: any): x is number {
        return typeof x === "number";
    }
忽略ts下一行报错
 // @ts-ignore

接口

interface

interface 可以重复声明 默认合并以前的
type重复声明会报错,默认替换所有不难为window声明类型断言,interface就可以

    // 声明一个 interface 接口
    interface InterfaceA {
        readonly num: number, // 只读属性
        str?: string // 可选类型
    }
    // 索引类型
    interface Indexes {
        [name: number]: string 
    }
    let obj: Indexes = {
         1: '1',
         2: '2',
         3: '3',
	}    
 	interface InterfaceB {
    }
    interface InterfaceC {
    }
    // 接口继承
    interface InterfaceD extends InterfaceB, InterfaceC {
    }
    // 接口泛型
    interface UserInfo<T> {
       id: T;
       age: number;
    }
    const userInfo: UserInfo<number> = {
       id: 123,
       age: 23,
    }	
	
	// interface 重复声明具有合并一起声明 的类型

在这里插入图片描述

type
	// type泛型
	type UserInfo<T> = { // 
        id: T,
        age: number
    }
    type Username = { // 
        name: number
    }
    //type的交叉类型 类似于 Interface 的 extends 继承
    const userInfo: UserInfo<string> & Username = {
       id: '123',
       age: 18,
       name:'李四'
   }
   
type 与 interface
//我们发现interface和type都可以用来定义类型, 那么在开发过程中,到底应该选择哪个
//1. 如果定义的是对象类型,那么通常推荐使用interface
//2. 如果定义的是非对象 function Direction 推荐使用type
//interface和type之间有什么异同
//1.interface可以重复声明  type不能重复声明
//2.type定义的别名, 别名是不能重复
声明一个类型判断的数组
    interface InterfaceA {
        num: number, // 必须有
        str?: string // 可选可不选
    }
	let arr:InterfaceA[]=[]

class 类

  • public:默认值
  • private : 只能在当前类中使用访问这个变量,实例和子类都不能获取和使用
  • protected:可以在类和子类中使用修改,实例上不能
  • 使用 static 开头的属性(方法)就是静态属性(方法),也称为类属性。只能在类中使用也是可以被继承的
  • 使用静态属性无需创建实例,可直接通过类来使用
abstract class Abs { // abstract 修饰的是抽象类 不能被实例

}
class Person {
    static hobby: string = '学习' //  static 静态属性只能通过类来获取
    readonly name: string //只读
    private sex: string  // private 修饰符私有属性  只能让元素在当前类中访问
    protected age: number  // protected  修饰符 类似  private 修饰 符 只是可以被 子类继承并且访问
    constructor(name: string, age: number, sex: string) {
        this.name = name
        this.sex = sex
        this.age = age
    }
    getPrivate() {
        console.log(this.sex); // ok
        console.log(Person.hobby); // 可以获取 static 静态属性
        // this.name='李四' // 不能 修改 "name" ,因为它是只读属性


    }
    getProtected() {
        console.log(this.age); // ok
    }

}
// 继承
class Child extends Person {
    public name: string  // public 默认成员修饰符 任何地方可以访问
    constructor(name: string, age: number, sex: string) {
        super(name, age, sex)
        this.name = name
    }
    // getPrivate() {
    //     console.log(this.sex);  //不能获取 属性“sex”为私有属性,只能在类“Person”中访问
    // }
    getProtected() {
        console.log(this.age);
    }

}
let chl = new Child('张三', 18, '男')
let per = new Person('张三', 18, '男')
// chl.sex   属性“sex”为私有属性,只能在类“Person”中访问
// chl.age  属性“age”受保护,只能在类“Person”及其子类中访问
Person.hobby //
Child.hobby // 
export {

}

声明全局变量 declare

declare class声明全局类
declare enum 声明全局枚举类型
declare namespace 声明(含有子属性的)全局变量

//命名空间主要目的就是将一个模块内部再进行作用域的划分, 防止一些命名冲突
export namespace Time {
    export function format(time: string){
        return "2021-11-12"
    }
}
export namespace Price {
    export function format(price: number) {
        return "$15,000"
    }
}

模块

export default ES6 默认导出
export = commonjs 导出模块
require(’’) 引入
整体引入 import * as
import … require 是 ts 官方推荐的方式:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值