ts基础入门学习之上篇

news2024/9/29 18:41:10

1.安装typescript编译器

npm i -g typescript

 安装之后使用tsc运行ts文件,然后会编译出对应的js文件,再通过node运行js文件,就能获得打印内容。

ts定义内容
function fn(people, date) {
  console.log(`hello${people},today is ${date}`);
}
fn("张三", "2023.2.15")

编译内容
function fn(people, date) {
    console.log("hello".concat(people, ",today is ").concat(date));
}
fn("张三", "2023.2.15");

但是会发现ts提示函数重复声明,这是因为ts和编译后的js文件函数名一样,造成的问题。

如何解决?,可以通过tsc --init来生成一个配置文件解决冲突问题,但是会报两个any类型错误,此时在配置文件将 "strict": true,注释就行了,ts每次编译需要手动输入指令,如何自动编译,可以通过tsc --watch解决。

ts报了错,编译以后js还是正常运行的,如果想优化编译,可以在优化的时候加一个tsc --noEmitOnError这样的一个参数,如果ts出现一些类型错误,就不让编译js文件了。

 2.降级编译

ts文件
function fn(people, date) {
  console.log(`hello${people},today is ${date}`);
}
fn("1236", "2023.2.15")

编译的js文件
function fn(people, date) {
    console.log(`hello${people},today is ${date}`);
}
fn("1236", "2023.2.15");

编译后的js文件中的模板字符串并没有被编译,这是因为语法不适应低版本浏览器,此时,在配置文件将"target": "es2016",改成"target": "es5"进行编译就行了。

function fn(people, date) {
    console.log("hello".concat(people, ",today is ").concat(date));
}
fn("1236", "2023.2.15");

3.配置严格模式

配置文件配置以下属性,都可以开启严格模式,三者有所不同

"strict":true,

"noImplicitAny":true,

"strictNullChecks":true

4.类型定义

//基元类型  还有any,对象,函数等类型
let str: string = "hello"
let num: number = 20
let boolean: boolean = true

//数组的定义方法
let arr: number[] = [1, 2, 3]
//泛型
let arr2: Array<number> = [4, 5, 6]


//?表示可传可不传,最终pt.y打印undefind
function printcorrd(pt: { x: number, y?: number }) {
  // console.log("x的坐标" + pt.x, "y的坐标" + pt.y);
  // if (pt.y !== undefined) {
  //   console.log("y的坐标" + pt.y);

  // }

}
printcorrd({ x: 20, y: 40 })


//联合类型,传一个值,参数是是其中任意类型即可
function fn(num: string | Number) {
  // console.log("num的值是" + num);

  if (typeof num === "string") {
    console.log(num);
  } else {
    console.log(num);

  }
}
fn(10)
fn("num")

5.类型定义别名

//类型别名 type进行类型别名的定义
type point = {
  x: number
  y: string
}
function fn(po: point) {
  console.log(po.x);

}
fn({
  x: 20,
  y: "wer"
})

6.接口

//interface关键字创建接口
interface point {
  x: number
  y: number
}
function fn(pt: point) {

}
fn({
  x: 20,
  y: 30
})

//扩展接口
interface school {
  name: string
}
interface person extends school {
  pencil: boolean
}
const pe: person = {
  name: "ls",
  pencil: true
}
console.log(pe.name);
console.log(pe.pencil);

7.断言

//断言as或<>
const mydiv = document.getElementById("main_div") as HTMLDivElement
const mydiv2 = <HTMLDivElement>document.getElementById("main_div")
// const x = "hello" as number //报错
const x = ("hello" as any) as number

8.symbol和bigint

const a: bigint = BigInt(100)
const b: bigint = 100n
//实际两个值是不等的,会报错两者没有重叠
const first = Symbol("age")
const second = Symbol("age")
if (first === second) {
  console.log('111');

}

9.类型缩小与真值缩小

//类型缩小就是从宽类型转化为窄类型的过程
//typeof 类型守卫

function pad(str: string | string[] | null) {
  //加上str &&自动类型转换,如果传入的是有效的str
  if (str && typeof str === "object") {
    for (const s of str) {
      console.log(s);

    }
  } else if (typeof str === "string") {
    console.log(str);
  } else {
  }
}


function all(value: number[] | undefined, value2: number) {
  if (!value) {
    return value
  } else {
    return value.map(item => {
      return item *= value2
    })
  }
}

console.log(all([1, 2], 3));//[3,6]
console.log(all(undefined, 3))//undefined

10.等值缩小,in操作符缩小,instanceof操作符缩小,分配缩小

function example(x: string | number, y: string | boolean) {
  // x.toUpperCase()
  // y.toLowerCase()
  //以上两个会报错,因为不一定是字符串

  //等值缩小,两值相等就只能是字符串
  if (x === y) {
    x.toUpperCase()
    y.toLowerCase()
  } else {
    console.log(x, y);

  }
}
example(122, true)


//in操作符缩小
type Fish = { swim: () => void }
type Bird = { flay: () => void }
//此时定义一个属性,并将其加入到函数中
type Human = { swim?: () => void, flay?: () => void }

function move(animal: Fish | Bird | Human) {
  if ("swim" in animal) {

    //animal可能是Fish|Human,此时使用断言
    return (animal as Fish).swim()
  }
  //可能是Bird|Human
  return (animal as Bird).flay()
}

//instanceof缩小
function value(x: Date | string) {
  if (x instanceof Date) {
    console.log(x.toUTCString());

  } else {
    console.log(x.toUpperCase());

  }
}
value(new Date())
value("hello ts")

//分配缩小
// let x:string|number
let x = Math.random() < 0.5 ? 1 : "hello ts"
//let x:number
x = 1
console.log(x);
//let x:string
x = "sayHello"
console.log(x);

11.类型谓词

type Fish = {
  name: string
  swim: () => void
}
type Bird = {
  name: string
  fly: () => void
}
//pet is Fish类型谓词
function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined
}
function getPet(): Fish | Bird {
  let fish: Fish = {
    name: "bear",
    swim: () => {

    }

  }
  let bird: Bird = {
    name: "pan",
    fly: () => { }
  }
  return true ? bird : fish
}
let pet = getPet()
if (isFish(pet)) {
  pet.swim()
} else {
  pet.fly()
}
const zoo: (Fish | Bird)[] = [getPet(), getPet(), getPet()]
const under: Fish[] = zoo.filter(isFish)
const under2: Fish[] = zoo.filter(isFish) as Fish[]

const under3: Fish[] = zoo.filter((pet): pet is Fish => {
  if (pet.name === "frog") {
    return false
  }
  return isFish(pet)
})

12.函数类型表达式

//函数表达式 fn:(a: string) => void  void表示没有返回值
function blue(fn: (a: string) => void) {
  fn("hello")
}
function current(s: string) {
  console.log(s);
}
blue(current)

//以上写法可以换一种写法
type greet=(a:string)=>void
function blue(fn:greet) {
  fn("hello")
}
function current(s: string) {
  console.log(s);
}
blue(current)

13.调用签名和构造签名

//调用签名 (someArg: number)
type DescribableFunction = {
  description: string
  (someArg: number): boolean
}
function doSomething(fn: DescribableFunction) {
  console.log(fn.description + "returned" + fn(6));
}
function fn1(n: number) {
  console.log(n);
  return true
}
fn1.description = "hello"
doSomething(fn1)

//构造签名
class Ctor {
  s: string
  constructor(s: string) {
    this.s = s
  }
}

type SomeConstructor = {
  new(s: string): Ctor
}
function fn(ctor: SomeConstructor) {
  return new ctor("hello")
}
const f = fn(Ctor)
console.log(f.s);

14.泛型--类型推断,泛型--使用受限值,泛型--指定类型参数

// function firstElement(arr:any[]){
//   return 100
// }
// 泛型<Type>
function firstElement<Type>(arr: Type[]): Type | undefined {
  return arr[0];

}
firstElement(["A"])
// <number>可写可不写,ts会进行推断,写了就不能写其他类型
firstElement<number>([1, 2, 3])
firstElement([])

//泛型<Input, Output>类型推断
function map<Input, Output>(arr: Input[], func: (arg: Input) => Output): Output[] {
  return arr.map(func)
}
const parsed = map(["A", "B"], (n) => parseInt(n))


//泛型--使用受限值
//此时会报错,提示类型Type上不存在length,然后通过关键字extends,强制定义length为number就可以了
function len<Type extends { length: number }>(a: Type, b: Type) {
  if (a.length >= b.length) {
    return a
  } else {
    return b
  }
}
const result=len([1,2],[3,5])
const res=len("as","bg")
const not=len(10,20)//报错,数字没有长度


//指定类型参数
function combie<Type>(arr1: Type[], arr2: Type[]): Type[] {
  return arr1.concat(arr2)
}
const arr = combie([1, 2, 3], [4, 6])
const arr3 = combie(["1", "2"], ["A"])
//以下会报错,因为ts解析中认为是number,所以后面的string就会报错,如果要解决加一个<string|number>就可以了,表示传入的是string或number
const arr4 = combie<string | number>([1, 2, 3], ["A", "B"])
console.log(arr4);

15.泛型函数编写准测

// 编写函数的通用准则
//1.可能的情况下使用参数本身,而不是进行约束,尽可能采用第一种写法
function first<Type>(arr: Type[]) {
  return arr[0]
}
function secend<Type extends any[]>(arr: Type) {
  return arr[0]
}
const a = first([1, 2, 3])
const b = secend([1, 2, 3])

//2.总是尽可能少地使用类型参数
function filter1<Type>(arr: Type[], fun: (arg: Type) => boolean) {
  return arr.filter(fun)
}
function filter2<Type, fun extends (arg: Type) => boolean>(arr: Type[],
  fun: fun) {
  return arr.filter(fun)
}
//3.如果一个类型的参数只出现在一个地方,请考虑你是否真的需要他
function greet(s: string) {
  console.log("hello" + s);

}
greet("world")
//很明显将str约束为string没什么必要
function greet2<str extends string>(s: str) {
  console.log("hello" + s);
}
greet2("hi")

16.函数及回调中的可选参数

//让number有一个100的初始值,此时n不能在赋?
function fn(n: number = 100) {
  console.log(n.toFixed());
  console.log(n.toFixed(3));
}
fn(123.45)
fn()

//回调中的可选参数
//当为回调写一个函数类型时,永远不要写一个可选参数,除非你打算在不传递该参数的情况下调用函数
function myForeach(arr: any[], callback: (arg: any, index?: number) => void) {
  for (var i = 0; i < arr.length; i++) {
    callback(arr[i], i)
  }
}
myForeach([1, 2, 3], (a) => console.log(a))
myForeach([1, 5, 3], (a, i) => console.log(a, i))
function myForeach(arr: any[], callback: (arg: any, index?: number) => void) {
  for (var i = 0; i < arr.length; i++) {
    //此时默认不写index
    callback(arr[i])
  }
}
myForeach([1, 5, 3], (a, i) => {
  console.log(i.toFixed());//会报错
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/353454.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++模板(一)

文章目录C模板&#xff08;一&#xff09;1. 泛型编程2. 函数模板2.1 函数模板格式2.2 模板原理2.3 模板实例化2.4 模板参数匹配原则3. 类模板3.1 类模板格式3.2 背景3.3 类模板的实例化C模板&#xff08;一&#xff09; 1. 泛型编程 前面我们学到了函数重载这个特性&#xf…

Zabbix“专家坐诊”第181期问答汇总

题一 Q&#xff1a;大佬们&#xff0c;有没有基础的 监控模板 触发器分享下&#xff1f; A&#xff1a;你可以试一下乐维免费版&#xff08;https://forum.lwops.cn/download &#xff09;&#xff0c;里面基本的模板全齐。 问题二 Q &#xff1a;orabbix监控查询SQL执行时…

如何保证数据库和缓存双写一致性?

前言 数据库和缓存&#xff08;比如&#xff1a;redis&#xff09;双写数据一致性问题&#xff0c;是一个跟开发语言无关的公共问题。尤其在高并发的场景下&#xff0c;这个问题变得更加严重。 我很负责的告诉大家&#xff0c;该问题无论在面试&#xff0c;还是工作中遇到的概率…

CAD中怎么旋转光标?CAD旋转光标的方法步骤

CAD中怎么旋转光标&#xff1f;浩辰CAD软件作为一款拥有自主核心技术的CAD平台软件产品&#xff0c;提供了CAD旋转光标命令&#xff0c;本节课程就和小编一起来了解一下浩辰CAD软件中CAD旋转光标的方法步骤吧&#xff01; CAD旋转光标命令启动方式&#xff1a; 1、命令行&…

Redis第三讲

目录 三、Redis03 3.1 Redis持久化之RDB 3.1.1 什么是RDB 3.1.2 备份是如何执行的 3.1.3 Fork 3.1.4 RDB持久化流程 3.1.5 dump.rdb文件 3.1.6 配置rdb文件生成位置 3.1.7 如何触发RDB快照以及保持策略 3.2 Redis持久化之AOF 3.2.1 什么是AOF 3.2.2 AOF持久化流程 …

Java反序列化漏洞——CommonsCollections3链分析

一、原理CC1链中我们是通过调用Runtime.getRuntime.exec()来执行系统命令&#xff0c;而另一个方向我们可以通过TemplatesImpl加载字节码的类&#xff0c;通过调⽤其newTransformer() 方法&#xff0c;即可执⾏这段字节码的类构造器&#xff0c;我们在类构造器中加入恶意代码&a…

【Seata】_01 分布式事务基础知识和常见的解决方案

本地事务 单一的数据库事务&#xff0c;ACID由数据库直接提供 分布式事务 一个服务调用操作两个数据库&#xff1b; 多个服务操作同一个数据库&#xff1b; 多个服务操作多个数据库&#xff1b; 分布式事务无法由数据库保证 Seata 分布式事务解决方案 Seata提供AT/TCC/SAG…

HDMI Audio InfoFrame

Audio InfoFrame 是HDMI Source向Sink传递当前音频流特性的一种InfoFrame。要求是至少每两帧图像就要传输一次Audio InfoFrame。Audio InfoFrame的传输可以是Data Island周期的任何时刻。 HDMI在音频的传输上&#xff0c;packet包的标准是按照IEC60958或者IEC61938来的。 Aud…

使用契约测试得不偿失?试试契约先行开发

契约维护的难题 如今微服务凭借其灵活、易开发、易扩展等优势深入人心&#xff0c;不同服务之间的集成和交互日渐繁多且复杂。这些服务之间交互的方式是多样的&#xff0c;常见的有 HTTP 请求和消息队列。在它们交互的过程中&#xff0c;会有服务的版本演进&#xff0c;交互信…

算法的时间复杂度与空间复杂度

…………………………………………………………………………………………………………………… ………………………………………………………………………加油…………………………………………………………………………. 如何衡量一个算法的好与坏呢&#xff1f;这是本篇的重点…

财报解读:硬件支撑思科增长,云平台何时能突围?

北京时间2023年2月16日&#xff0c;美国网络设备老牌巨头思科公布了其2023财年第二季度财报&#xff0c;业绩超预期。 据思科财报显示&#xff0c;其2023财年Q2实现营收136亿美元&#xff0c;分析师预期为134.3亿美元&#xff1b;同时给出大超预期的业绩指引&#xff0c;思科预…

jetson nano(ubuntu)编译Qt creator

文章目录一.apt安装二.源码编译安装1.Qt Creator源码下载2.相关软件安装cmakeninjallvm/clang3.Qt Creator源码编译一.apt安装 sudo apt-get install qtcreatorapt安装的版本只有4的&#xff0c;版本较低&#xff0c;只有qmake进行项目配置&#xff0c;6版本以上可以使用cmake…

7大体系防作弊,牛客放大招了!严肃笔试客户端上线!

如果问起学生对在线笔试的印象&#xff0c;“不公平”和“不服气”占了半壁江山。学生认为很多企业的在线笔试系统并不完善。原因一&#xff0c;不能有效地规避部分学生的作弊行为&#xff1b;原因二&#xff0c;在线考试系统不稳定&#xff0c;bug频出&#xff0c;导致笔试发挥…

CURL error 60: SSL certificate problem: certificate has expired

项目使用guzzleHttp做的一个接口&#xff0c;报错&#xff1a;certificate has expired 因为在linux centos环境与window环境有所不同&#xff0c;在此记录一下解决过程。 目录 报错提示 原因 解决方式 1.去掉guzzlehttp的验证 2.更新CA证书 总结 报错提示 cURL error 60…

RadZen运行和部署,生成业务web应用程序

RadZen运行和部署,生成业务web应用程序 快速简单地生成业务web应用程序&#xff0c;可视化地构建和启动web程序&#xff0c;而我们为您创建新代码。 从信息开始 连接到数据库。Radzen推断您的信息并生成一个功能完备的web应用程序。支持MSSQL REST服务。 微调 添加页面或编辑生…

人工智能、机器学习和深度学习有哪些区别?

人工智能在如今越来越火&#xff0c;诸多词汇时刻萦绕在我们耳边&#xff1a;人工智能、机器学习、深度学习等。不少人对这些高频词汇的含义及其背后的关系总是似懂非懂、一知半解。为了帮助大家更好地理解人工智能&#xff0c;这篇文章用最简单的语言解释了这些词汇的含义&…

tomcat-container 源码分析

说明 本文基于 tomcat 8.5.x 编写。author blog.jellyfishmix.com / JellyfishMIX - githubLICENSE GPL-2.0 tomcat 的 container 容器 tomcat 由 connector 和 container 两部分组成&#xff0c;connector 接收到请求后&#xff0c;先将请求包装为 request&#xff0c;然后…

六、H5新特性

文章目录一、H5的兼容二、H5新增特性2.1 语义化标签2.2 增强表单2.3 音频、视频一、H5的兼容 支持 HTML5的浏览器包括Firefox(火狐浏览器)&#xff0c;IE9及其更高版本&#xff0c;Chrome(谷歌浏览器)&#xff0c;Safari,Opera等&#xff0c;国内的遨游浏览器&#xff0c;以及…

【Kubernetes 企业项目实战】07、最新一代微服务网格 Istio 入门到企业实战(上)

目录 一、Istio 介绍 1.1 什么是 service mesh 1.2 什么是 Istio 1.2.1 服务注册和发现 1.2.2 服务度量 1.2.3 灰度发布 1.3 Istio 核心特性 1.3.1 断路器 1.3.2 超时 1.3.3 重试 1.3.4 多路由规则 二、架构和原理 2.1 Istio 架构 2.1.1 数据平面由一组以 Sideca…

【Spring】手动实现简易AOP和IOC

前言 XML&#xff1a;通过Dom4j对XML进行解析和验证。 IOC&#xff1a;通过获取要创建对象的Class类型、构造函数后&#xff0c;通过反射来实现。 AOP&#xff1a;通过使用JDK动态代理和Cglib动态代理实现。 一、解析XML 1.1、解析bean标签 /*** 解析bean标签* param xmlBean…