TypeScript的基本使用

  1. 如何运行ts文件以及如何把ts文件转化为js文件

  1. JavaScript对应的ts类型

  1. ts的其他类型

  1. 断言、非空断言 、?? 、!! 和类型缩小、可选链和字面量推理

  1. 函数的使用

  1. 类的使用

  1. 接口的使用

  1. 泛型的使用

  1. 类型得查找

10.tsconfig.json文件

11.注意

1.如何运行ts文件以及如何把ts文件转化为js文件

1)如何把ts文件转化为js文件

a.安装包typescript

b.终端执行tsc 文件名.ts

npm install -g typescript 

2).如何运行ts文件

建立package包 npm init -y

安装包@types/node ts-node

修改package文件的test

运行test命令

npm init -y
npm i @types/node --save-dev
npm i ts-node -g 

"scripts": {
    "test": "ts-node index.ts"
  },

最后node终端执行node test

2.JavaScript对应的ts类型

在Javascript中 基础数据类型有Number、String、Boolean、Null、Undefined、Symbol,复杂数据类型有Array和Object

// number类型
let number1:number
number1=1

// string类型
let string1:string
string1='string'

// boolean类型
let boolean1:boolean
boolean1=false

// null类型
let null1:null
null1=null

// undefined类型
let undefinded1:undefined
undefinded1=undefined

// symbol类型
let symbol1:symbol
// Symbol的S是大写
symbol1=Symbol(1)

// 数组类型和元组类型
// 数组有两种写法 一般用第一种 第二种在jsx里面会有冲突
let arr:string[]
arr=['1','2']
// 不是Array[string] 而是Array<string>
let arr1:Array<string>
arr1=['1','2']
// 元组类型 和数组类型得区别是元组类型里面的类型具体到索引并且可以不同
let tuple1:[string,number]
tuple1=['1',1]

// object类型
let obj:object
// obj.obj1=1  不能赋值和取值
obj={obj1:1,obj2:2}

3.ts的其他类型

ts还有any、nerver、unknow、void、可选类型、字面量类型、联合类型、交叉类型和枚举类型

1)any、nerver、unknow、void、可选类型、字面量类型、联合类型、交叉类型

// any类型
let any:any
any=1

// unknown类型
let unknow:unknown
unknow=1

// nerver类型
// 不能直接赋值nerver
// let nerver:nerver
 function name1(params:string):string {
 switch(typeof params){
 case  'string':
    return 'string';
    default:
    let check:never=params
    return check
}   
}

// void类型
// 不是volid 是void
function fn2():void{
  console.log('volid');
}

// 字面量类型
let ab:'jh'
ab='jh'

// 联合类型
let combile:'ab'|'a'
combile='a'

// 交叉类型
let combile1:'ab'&'a'

//可选类型
interface obj {
    name?:string,
    nameq:number
}
let obj1:obj={
    nameq:1,
}

2)枚举类型(就是有默认值的联合类型)

// 枚举类型 基本使用
enum Drection {
  right,
  bottom,
}
function DrectionFn(type:Drection){
  switch (type){
    case Drection.right:
    return 'right'
    case Drection.bottom:
      return 'bottom'
    default:
      return 'notFund'
  }
}
// 枚举类型是有默认值的 如果不给默认值 默认值就是索引值 即第一个值是0 后面累加1
console.log(DrectionFn(0));

// 当第一个值赋值是数字的时候 后一个的默认值就是前一个的加1
enum Drection2 {
  right=3,
  bottom,
}
function Drection2Fn(type:Drection2){
  switch (type){
    case Drection2.right:
    return 'right'
    case Drection2.bottom:
      return 'bottom'
    default:
      return 'notFund'
  }
}
// 会和bottom匹配 因为前一个是3 这个默认就是4
console.log(Drection2Fn(4));


// 如果前一个不是数字 而是字符串 后一个必须给默认值 否则无法运行代码
// enum Drection3 {
//   right='right',
//   bottom,
// }
enum Drection3 {
  right='right',
  bottom='bottom',
}
function Drection3Fn(type:Drection3){
  switch (type){
    case Drection3.right:
    return 'right'
    case Drection3.bottom:
      return 'bottom'
    default:
      return 'notFund'
  }
}
// 传入的必须是Drection3类型 数字除外 不然无法运行
// console.log(Drection3Fn('right'));
console.log(Drection3Fn(Drection3.right));

4.断言、非空断言 、?? 、!! 和类型缩小、类型保护、可选链和字面量推理

字面量推理就是根据上下文推理出变量的类型,从而不需要写类型

可选链就是它的作用是当对象的属性不存在时,会短路,直接返回undefined,如果存在,那么才会继续执行

类型缩小就是可以缩小比声明时更小的类型,这个过程称之为 缩小(通过typeof等判断)

如果是等值 如typeof padding === "number 可以称之为 类型保护

// 断言 (只能转换成具体或更不具体的 不能强制转换 而且断言是变量或dom或函数然后as 类型)
let abss:unknown
abss='a' as string


// ??和|| 是有区别的 区别在于0和false
// || 如果前面不是null undefined 0 false就返回 否则返回后面部分
// ?? 如果前面不是null undefined就返回 否则返回后面部分
// && 如果前面是null undefined 0 false就返回 否则返回后面部分
console.log(1??2);//1
console.log(1||2);//1
console.log(1&&2);//2
console.log(0??2);//0
console.log(0||2);//2
console.log(0&&2);//0

// 非空断言  我们传入的一定是有值的 所以可以用非空断言
//me如果不给any类型会说暗指的any类型在ts文件内报错 所以必须添加类型 
function basss(me?:any):number{
 return me.length
}
// 数字类型是没有长度的 
console.log(basss('989'));

// 可选链
let obj4={
    num:{
        num1:3
    }
}
// 如果obj4的num里面没有num1 返回undefined 如果有继续往下取num1
console.log(obj4.num?.num1);

5.函数的使用

// 函数(内容包括默认参数 可选参数(其实是一个类型和undefined的组合)参数是对象类型 剩余参数 匿名函数的类型 函数重载) 
// 函数的定义 两种方式定义 type和interface 一般type定义函数 interface定义对象 interface定义是可以重复的
type fn8=()=>void
function fn12(fn:fn8){
    console.log(22);
}
const fn13:fn8=()=>{
    console.log(22);
}
interface fn14{
 ():void
}
const f21:fn14=()=>{
    console.log(22);
}
function fn3(num=1,num2?:string){
    console.log(num);
}
fn3(2)

// 函数 对象参数 不是这样写的
// function fn4({a:string,b:number}){
//     console.log(a);
// }
function fn4(ab:{a:string,b:number}){
    console.log(ab.a);
}
let obj5={a:'1',b:1}
fn4(obj5);

// 函数剩余参数
fn4({...obj5});

// 匿名函数:就是没有名字的函数 匿名函数的参数会被自己推导
(function (str){
    console.log('我是匿名函数');
})('匿名函数')

// 函数的重载 当调用的时候先会去匹配函数重载类型对不对 然后再执行函数的实现 fsn5的实现体写在下面 
// 函数重载
function fsn5(num:string,num2:number):void;
function fsn5(num:number,num2:number):void;
// 函数实现
function fsn5(num:any,num2):void{
    console.log(333);
}
fsn5('12',1)

6.类的使用

// 类的学习 继承 public prective protect readonly四种类型 get 和set 抽象类
// 继承
class Person {
static num=3
   private age1:number=2
   protected age3:number=3
   readonly age4:number=3
    age:number
    name:string
    get (){
        return this.age1
    }
    constructor(x:number,y:string){
        this.age=x
        this.name=y
    }
}
class Student extends Person {
    student:boolean
    get3 (){
        // private是不能访问的
        //  this.age1
        //  this.age3
    }
    constructor(x:boolean,y:number,z:string){
        super(y,z)
        this.student=x
    }
}
const xiaoHong=new Student(true,1,'xiaohong')
const xiaoHong2=new Person(1,'xiaohong')
// 当打印的时候 private的age1都是可以打印出来的
console.log(xiaoHong);
console.log(xiaoHong2);
// 但是这样去取的时候 是取不到的 会报错 
// console.log(xiaoHong.age1);
// console.log(xiaoHong2.age1);
// 如果要取 只能通过set get
console.log(xiaoHong.get());
console.log(xiaoHong2.get());
console.log(xiaoHong.age4);
console.log(xiaoHong2.age4);
console.log(Person.num);

// 结论 private在子类和类的实现中都是可以打印出来 但是不能直接获取和修改 但是可以通过方法获得
// protected和private的区别 protected在子类是可以用this访问的
// readonly 只能读取 不能修改 子类和当前类实现能访问 static可以通过对象访问 但是不能通过实现访问
// 抽象类
abstract  class Ab {
 abstract num:number
}
// 抽象类变成实体类 是通过继承 而不是ts类型方式 下面写法错误
// class Abc:Ab{
// }
// 记住类里面的赋值不是:而是等于号赋值
class Abc extends Ab{
    num=1
}
let Abs=new Abc()

7.接口的使用

// 接口:定义对象的时候 实现 索引 只读 可选 定义函数  继承

// 接口定义对象 只读 可选
interface obj3 {
    num:number
    // 可选
    num1?:number
    // 只读 只能获取 不能赋值 赋值会编译报错
    readonly num2:number
}

// 实现
let obnj:obj3={
    num:2,
    // num1:3,
    num2:3
}

// 索引类型
// 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。 这是因为当使用 number 来索引时,JavaScript 会将它转换成 string 然后再去索引对象。
interface obj33{
    [index:number]:string
    [str:string]:string
}
// number索引 一般用在数组里
interface obj333{
    [index:number]:number
}
let bj:obj333=[3,8,9]
interface obj3339{
    [index:string]:number
}
let ou:obj3339={
 'jkh':11,
}

// 接口在函数的使用
interface ij{
    ():void
}
const Af:ij=()=>{
    console.log(78);
}
Af()

8.泛型的使用

// 泛型的使用 如何使用 调用 传入多个类型 泛型在接口的应用 在类的使用 在函数的使用 泛型约束

// 如何使用
// 这就是一个函数加上类型 第一个number是参数类型 第二个number是返回值类型
function generic(num:number):number{
  return  num
}
// 当使用泛型  当使用泛型的时候 只需在函数名后加<T>即可
function generic2<T>(num:T):T{
  return  num
}


// 调用的时候有两种方式 第一种通过类型推导
console.log(generic2(2));
// 第二种 传入类型  还是在函数名后面写<T>
console.log(generic2<number>(2));


// 泛型扩展 传入多个类型
function generic3<T,E>(ar1:T,ar2:E):T{
  return ar1
}
console.log(generic3(2,'jkh'));

// 泛型在接口的应用 泛型的类型可以给默认值 给默认值后 下面可以只写一个 默认和这里的第一个匹配
interface Foo<T,E=string>{
  generic:T,
  generic1:E,
}
const genericInterface: Foo<number>={
  generic:1,
  generic1:'generic1'
}
console.log(genericInterface);

// 泛型在类的使用 这个T和调用传人的参数不是同一个
class genericClass<T>{
  // 可以用在这以及规定调用时候传入的类型
  generic:T
  generic1
  // 调用时候的限定
  constructor(x:T){
    // 对于类 只有带有继承的才能用super 注意上面定义的值必须要有初始化 就是要么赋值默认值 要么就是contructor里面调用
    this.generic=x
    this.generic1=x
  }
}
const genericInstance=new genericClass<number>(2)
console.log(genericInstance);


// 泛型在箭头函数的使用
const genericFunction=<T>(num:T):T=>{return num}
console.log(genericFunction<number>(2));

// 泛型约束 就是通过继承 限制传入类型 不能多继承
interface str1{
  string1:string
}
interface num1{
  number:number
}
interface numStr extends str1,num1{
}
const numStr1:numStr={
  string1:'87',
  number:12
}
function bounds<T extends num1>(num:T):T{
 return  num
}
console.log(bounds<numStr>(numStr1));

9.类型的查找

1)内置类型声明:(是typescript自带,比如Math、Date等内置类型)

2)外部定义类型声明:(在自己库中进行类型声明(编写.d.ts文件),比如axios,通过社区的一个公有库DefinitelyTyped存放类型声明文件 npm使用即可)

该库的GitHub地址:https://github.com/DefinitelyTyped/DefinitelyTyped/

该库查找声明安装方式的地址:https://www.typescriptlang.org/dt/search?search=

3)自己定义类型声明:建立.d.ts文件,声明类型即可 注意ts-node会编译的时候会忽略.d.ts文件,需要在typeScript.json进行配置types,注意types里面文件名不需要尾缀,带尾缀会报ts找不到该文件错误,.d.ts文件的位置是哪里都可以,也不需要引入

// 声明模块
declare module 'lodash' {
    export function chunk(arg:string[],num:number):any[];
}
// 声明变量
declare let stru:string
// 声明函数
declare function strua():void
// 声明类
declare class Person{
    name:string
    constructor(name:string)
}
// 声明命名空间
declare namespace ${}
{
    "compilerOptions": {
      "types": ["./src/declaration"],
      "esModuleInterop": true,      
    },
}

10.tsconfig.json文件

“ tsc --init ” 初始化tsconfig.json 文件 tsc 文件名.ts 执行后,会自动生成js文件

tsconfig.json是用于配置TypeScript编译时的配置选项:https://www.typescriptlang.org/tsconfig

11.注意:

1)TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension “.ts“

package.json中删除

"type":"module"

当通过tsc命令或ts-node运行文件时,系统会去读取tsconfig.json文件,我们对于其模块化的指定需写在这个文件内,而不是package文件,在ts配置文件内配置转换成commonjs代码执行"module": "commonjs",转换成es6模块执行,如果是es6就es6执行

2)两个ts文件都在同一个目录下,每个ts 都定义了相同变量就会报错,为什么不同文件下的ts,他们却公用了同一个全局环境?

两个ts文件都在同一个目录下,每个ts 都定义了相同变量就会报错,为什么不同文件下的ts,他们却公用了同一个全局环境?求解

在默认情况下,当你开始在一个新的 TypeScript 文件中写下代码时,它处于全局命名空间中,使用全局变量空间是危险的,因为它会与文件内的代码命名冲突。改成使用文件模块,文件中包含import或者export,就会在当前文件中创建一个本地作用域 这是ts特性之一。防止你写重复的变量名。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值