当前位置:网站首页>TypeScript学习
TypeScript学习
2022-06-27 19:03:00 【优雅 的猪】
1.TypeScript介绍
TypeScript是一种由微软开发的开源、跨平台的编程语言。它是JavaScript的超集,最终会被编译为JavaScript代码。2012年10月,微软发布了首个公开版本的TypeScript,2013年6月19日,在经历了一个预览版之后微软正式发布了正式版TypeScript。TypeScript的作者是安德斯·海尔斯伯格,C#的首席架构师。它是开源和跨平台的编程语言。是为大型应用的开发而设计,并且可以编译为JavaScript,是 JavaScript 的一个超集,主要提供了类型系统和对 ES6+ 的支持
TypeScript 可以编译出纯净、 简洁的 JavaScript 代码,并且可以运行在任何浏览器上、Node.js 环境中和任何支持 ECMAScript 3(或更高版本)的JavaScript 引擎中,类型系统允许 JavaScript 开发者在开发 JavaScript 应用程序时使用高效的开发工具和常用操作比如静态检查和代码重构。
2.TypeScript安装
2.1 全局安装
npm install -g typescript
2.2 检查是否安装成功 ,查看版本
tsc -V
3.TypeScript代码编译
新建 typescript/hello.ts文件,使用VSCode打开
编写ts代码
console.log('hello TypeScript')
3.1手动编译
命令行输入
tsc helloworld.ts
输出结果为一个hello.js文件 ,这个就是将ts代码编译后的js代码
然后在命令行输入
node hello.js
控制台输出
hello TypeScript
手动编译就是当我们每次写完代码,都需要重新tsc hello.ts一下才能编译成js代码 ,比较麻烦
3.2自动编译
3.2.1生成tsconfig.json文件
tsc --init
3.2.2 修改tsconfig.json配置
"outDir": "./js",
"strict": false
3.2.3 启动监视任务
终端 -> 运行任务 -> 监视tsconfig.json
4.TypeScript基础类型
TypeScript 支持与 JavaScript 几乎相同的数据类型,此外新增一些类型方便(比如枚举)我们使用。
4.1 字符串类型
let str: string = 'test'
4.2 数字类型
let num: number = 12
4.3 null类型
let n: null = null
4.4 undefined类型
let u: undefined = undefined
4.5 布尔类型
let b:boolean = true
4.6 any类型 (少用)
let a: any = '我是任意类型的值'
a = 12
a = true
a = null
a = undefined
a = () => {}
let str1: string = 'wft'
str1 = a //不报错,any类型就相当于关闭了我们ts类型检查,所以尽量不使用
4.7 unknown类型
// 未知类型
let unk: unknown = '12'
let str2: string = 'www'
// str2 = unk //报错,如果有未知类型,我们使用unknow来代替any
4.8 联合类型
let unio: string | number | boolean = true
unio = '121'
unio = 10
4.9 数组类型
let arr1: number[] = [1,2,3]
let arr2: Array<string> = ['1', '2', '3']
let arr3: any[] = [1, '2', false, null, undefined]
4.10 元组Tuple类型
数组长度固定
let arr4:[string, number] = ['1', 2] // 正确
// arr4 = ['1',2, 3] //报错
// arr4 = [2, '1'] // 报错
4.11 枚举类型
// 枚举数值默认从0开始依次递增
// 根据特定的名称得到对应的枚举数值
enum Flag1 {
name = 'wft',
age = 18
}
enum Flag2 {
name,
age = 18,
height
}
enum Flag3 {
name,
age,
height
}
let flag1: Flag1 = Flag1.name
let flag2: Flag2 = Flag2.height
let flag3: Flag3 = Flag3.height;
console.log(flag1, flag2, flag3); // wft 19 2
4.12 void类型
void类型一般用于函数没有返回值,即默认值返回值为undefined
(function fn(): void {
console.log('我没有返回值~~');
})()
4.13 never类型
这个也是表示没有任何的返回值,他和void的区别就是,void可以返回,只不过是没有值(undefined),但是never是返回undefined都不行,压根就不能有返回,一般用于抛出错误
function err(): never {
throw new Error('抛出错误')
}
4.14 类型断言
类型断言就是可以手动指定一个值的类型。通过类型断言这种方式就好比告诉编译器:“相信我,我知道自己在干什么”, 它没有运行时的影响,就代码该怎么执行怎么执行,只是在编译阶段起作用,能够编译通过。两种语法:1.尖括号语法 2.as关键字
// 类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。
// 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。
// 它没有运行时的影响,只是在编译阶段起作用。
// TypeScript 会假设你,程序员,已经进行了必须的检查。
// 方式一: <>值
// 方式二: as 关键字
function getLength(x: number | string): number {
if ((<string>x).length) {
return (x as string).length
} else {
return x.toString().length
}
}
console.log(getLength('abcd'), getLength(1234), '---->>') // 4 4
4.15 类型推断
TS会在没有明确的指定类型的时候推测出一个类型
有下面2种情况: 1. 定义变量时赋值了, 推断为对应的类型. 2. 定义变量时没有赋值, 推断为any类型
// 定义变量时赋值了,推断为对应的类型
let w = 110 // number类型
// w = 'hahha' // 报错
// 定义变量时没赋值,推断为any
let wn; //any类型
wn = 12
wn = '1212'
5.TypeScript函数
和 JavaScript 一样,TypeScript 函数可以创建有名字的函数和匿名函数。你可以随意选择适合应用程序的方式,不论是定义一系列 API 函数还是只使用一次的函数。
TypeScript 为 JavaScript 函数添加了额外的功能,让我们可以更容易地使用
5.1 函数声明
function add (a: number, b: number): number {
return a + b
}
add(1,2)
5.2 函数表达式
const add = function(a: number, b: number): number {
return a + b
}
add(1,2)
5.3 必选参数
function getInfo(name: string, age: number) {
return `${name}今年${age}岁了`
}
getInfo('小王', 12)
5.3 可选参数
function getInfo(name: string, age?: number) {
return age ? `${name}----${age}` : `---${name}---`
}
getInfo('小王', 12)
getInfo('我是小王')
5.4 默认参数
注意:可选参数不能设置默认值
function getInfo(name: string = '小王', age: number = 20) {
return `${name}今年${age}岁了`
}
getInfo('小王', 12)
getInfo()
5.5 剩余参数
function myInfo(name: string, ...args: string[]) {
console.log(name, args)
}
myInfo('小王', '1', '2', '3')
5.6 函数重载
函数重载指的是形参不同的多个同名函数
5.6.1 例1
function info(name: string): string;
function info(name: string, age: number): string
//重载函数签名:就是把声明中出现的参数都写出来,如果可选,就使用可选参数,一个变量名可以使用多种类型用组合类型
function info(name: string, age?: number): string {
if(age) {
return `${name}今年${age}岁了`
} else {
return `我叫${name}`
}
}
console.log(info("zhangsan"));
console.log(info("lisi", 20));
// console.log(info(123));// error
5.6.2 例2
function add (x: string, y: string): string
function add (x: number, y: number): number
// 定义函数实现
function add(x: string | number, y: string | number): string | number {
// 在实现上我们要注意严格判断两个参数的类型是否相等,而不能简单的写一个 x + y
if (typeof x === 'string' && typeof y === 'string') {
return x + y
} else if (typeof x === 'number' && typeof y === 'number') {
return x + y
}
}
console.log(add(1, 2))
console.log(add('a', 'b'))
// console.log(add(1, 'a')) // error
6.接口
TypeScript 的核心原则之一是对值所具有的结构进行类型检查。我们使用接口(Interface)来定义对象的类型。接口是对象的状态(属性)和行为(方法)的抽象(描述)
接口可以在定义对象(或者类)的时候去限制对象(或者类)的结构
接口中所有的属性都不能有实际的值
接口只定义对象的结构,而不考虑实际值
接口中所有的方法都是抽象方法
6.1 属性类型接口
6.1.1 必选属性
interface Person {
id: string,
name: string,
age: number
}
const IPerson: Person = {
id: '001',
name: 'wft',
age: 18
}
6.1.2 可选属性
interface Person {
id: string,
name: string,
age: number,
sex?: string
}
const IPerson: Person = {
id: '001',
name: 'wft',
age: 18,
// sex: '男' // 可以没有
}
6.1.3 只读属性
interface Person {
readonly id: string,
name: string,
age: number
}
const IPerson: Person = {
id: '001',
name: 'wft',
age: 18
}
// IPerson.id = '121212' // 不可修改
6.1.4 对象属性
interface Info {
height: string,
}
interface Person {
id: string,
name: string,
age: number,
info: Info // 对象
}
const IPerson: Person = {
id: '001',
name: 'wft',
age: 18,
info: {
height: '1.88'
}
}
6.1.5 任意key
interface Person {
id: string, // id是必须有的属性
[PropName: string]: any // 其他的随意加什么
}
const IPerson: Person = {
id: '001',
name: 'wft',
age: 18
}
6.2 函数类接口
接口可以描述函数类型(即参数的类型与返回的类型)
interface Reversal {
(str1: string, str2: string): string
}
const strReverse: Reversal = (str1: string, str2: string): string {
return (str1 + str2).split('').reverse().join('')
}
console.log(strReverse('123', '456'));
6.3 类类型接口
interface Animal {
name: string,
eat(food: string): void
}
class Cat implements Animal {
name: string
constructor(name: string) {
this.name = name
}
eat(food: string): void {
console.log(`${this.name}吃${food}`);
}
}
let cat = new Cat('猫')
cat.eat('鱼')
一个类实现多个接口 :
interface Animal1 {
name: string,
eat(food: string): void
}
interface Animal2 {
age: number,
fn(str: string): void
}
class Cat implements Animal1, Animal2 {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
eat(food: string): void {
console.log(`${this.name}吃${food}`);
}
fn(): void {
console.log(`${this.name}今年${this.age}岁了`);
}
}
let cat = new Cat('猫', 2)
cat.eat('鱼')
cat.fn()
6.4 接口继承
接口和类一样,也可以相互继承,这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。
// 动物接口
interface Animal {
name: string,
eat(food: string): void
}
// 飞行动物
interface Fly extends Animal {
wing(): void
}
class Eagle implements Fly {
name: string
constructor(name: string) {
this.name = name
}
eat(food: string): void {
console.log(`${this.name}吃${food}`);
}
wing(): void {
console.log('老鹰捉小鸡');
}
}
let fly = new Eagle('老鹰')
fly.eat('小鸡')
fly.wing()
7.类
对象是由类创建出来的,通过new关键字 ,当我们new的时候,就自动执行class中的constructor方法,创建出一个对象,并改变了this指向,指向创建出的对象
7.1 类的基本使用
class C {
name: string // 省略了前面的public(默认)关键字
constructor(name:string) {
this.name = name
}
getName(): void {
console.log(`我叫${this.name}`);
}
}
let c = new C('wft')
c.getName()
7.2 类的继承
class C {
name: string // 省略了前面的public(默认)关键字
constructor(name:string) {
this.name = name
}
getName():void {
console.log(`我叫${this.name}`);
}
}
class D extends C {
age: number
// 类的继承一旦使用了constructor就要使用super方法调用父类的构造方法
constructor(name: string, age: number) {
super(name)
this.age = age
}
getInfo(): void {
super.getName() // 调用父类的方法
console.log(`${this.name}今年${this.age}了`);
}
}
let d = new D('wft', 18)
d.getInfo()
d.getName()
7.3 属性修饰符
class AttrTest {
public name: string // 公共类型的属性(默认),内部、外部、子类都可以访问到
private age: number // 私有属性,只能在类内部访问
protected sex: string // 在内部和子类可以访问、外部不能访问
readonly id: string // 只读属性,只读属性必须在声明时或构造函数里被初始化
constructor() {
console.log('属性测试')
}
}
7.4 静态属性
上面讨论的都是类的实例成员,仅当类被实例化的时候才会被初始化的属性
静态属性不需要实例化,只需要static关键字,就可以通过类名直接访问
方法也是一样,这里就不再赘述
class AttrTest {
static sta: string = '我是静态属性'
constructor() {
console.log('属性测试')
}
}
console.log(AttrTest.sta);
7.5 抽象类
抽象类就是提供给其他类继承的基类,不能直接被实例化
通过 abstract关键字定义抽象类和在抽象类内部定义抽象方法
abstract class C {
name: string // 省略了前面的public(默认)关键字
constructor(name:string) {
this.name = name
}
abstract fn(): void //抽象方法不包含具体实现并且必须在派生类中实现
getName():void {
console.log(`我叫${this.name}`);
}
}
class D extends C {
age: number
// 类的继承一旦使用了constructor就要使用super方法调用父类的构造方法
constructor(name: string, age: number) {
super(name)
this.age = age
}
fn(): void { // 子类中必须实现抽象父类中的抽象方法
console.log('父类中的抽象方法');
}
getInfo(): void {
super.getName() // 调用父类的方法
console.log(`${this.name}今年${this.age}了`);
}
}
8.泛型
泛型指的就是定义函数、接口或者类的时候我们不确定会传入什么类型的值,则不预先指定类型 ,而在使用的时候再指定具体类型的一种特性
8.1 函数泛型
/**
* 例1
* @param value 不确定什么类型,我们传入什么类型就是什么类型
* @returns 返回长度为1的包含value的数组
*/
function test<T>(value: T): T[] {
return [ value ]
}
/**
* 例2
* 创建一个包含count个value的数组
* @param value 不确定什么类型,我们传入什么类型就是什么类型
* @param count 数字类型
* @returns 返回一个未知类型的数组
*/
function createArr<T>(value: T, count: number): T[] {
const arr:T[] = []
for(let i = 0; i < count; i++) {
arr.push(value)
}
return arr
}
console.log(createArr('push', 5))// [ 'push', 'push', 'push', 'push', 'push' ]
8.2 多个泛型参数的函数
/**
* 例3
* 多个泛型参数的函数
* @param value1 未知类型
* @param value2 未知类型
* @returns 返回长度为2的不确定类型的元组
*/
function test<K, V>(value1: K, value2: V): [K, V] {
return [value1, value2]
}
console.log(test(() => 1, 1)); //[ [Function], 1 ]
8.3 泛型接口
interface IFn<T> {
(value: T): T
}
const fn: IFn<string> = (value: string) => value
8.4 泛型类
class TTest<T> {
name: T
age: T
fn: (a: T, b:T) => T
constructor(name: T, age: T) {
this.name = name
this.age = age
}
}
// 我们在实例化的时候传入泛型的类型,就是为泛型指定一个类型
let o = new TTest<string>('wft', '12')
o.fn = function(a, b) {
return a + b
}
学习参考:
边栏推荐
- 实现字符串MyString
- Goldfish rhca memoirs: do447 managing projects and carrying out operations -- creating job templates and starting jobs
- Massive data attended the Lanzhou opengauss meetup (ECOLOGICAL NATIONAL trip) activity, enabling users to upgrade their applications with enterprise level databases
- Zhongang Mining: the largest application field of new energy or fluorite
- Implementation string mystring
- MySQL速成——第一天--基础入门
- Share how I take notes
- Love math experiment | phase VI - Financial anti fraud case study
- 大促场景下,如何做好网关高可用防护
- Show the comprehensive strength of strong products, and make the first show of 2022 Lincoln aviator in Southwest China
猜你喜欢
Serveur mandataire SQUID
Oracle的CTAS能不能将约束等属性带到新表?
BTC and eth recapture the lost land! Leading the market recovery? Encryption will enter the "ice age"!
No wonder people chose apifox instead of postman
通过CE修改器修改大型网络游戏
Focus! Tips for installing fonts on domestic computers
Zhongang Mining: the largest application field of new energy or fluorite
Covering access to 2w+ traffic monitoring equipment, EMQ creates a new digital engine for all elements of traffic in Shenzhen
Experience Navicat premium 16, unlimited reset, 14 day trial method (with source code)
College graduation thesis management system based on wechat applet graduation design
随机推荐
体验Navicat Premium 16,无限重置试用14天方法(附源码)
[array]bm99 clockwise rotation matrix - simple
覆盖接入2w+交通监测设备,EMQ 为深圳市打造交通全要素数字化新引擎
College graduation thesis management system based on wechat applet graduation design
eval函数,全局、本地变量
Oracle的CTAS能不能将约束等属性带到新表?
Share an experience of self positioning + problem solving
Original translation | comparison of machine learning model service tools: kserve, Seldon core and bentoml
众昂矿业:新能源或成萤石最大应用领域
Pycharm common functions - breakpoint debugging
[STL programming] [common competition] [Part 3]
白嫖红队goby&POC,叫你如何白嫖?
Love math experiment | phase VI - Financial anti fraud case study
花了6个月时间完成本科优秀毕业设计,我做了什么?
划重点!国产电脑上安装字体小技巧
Runmaide medical opened the offering: without the participation of cornerstone investors, the amount of loss doubled
【STL编程】【竞赛常用】【part 2】
Serveur mandataire SQUID
动物养殖生产虚拟仿真教学系统|华锐互动
I haven't thought about the source for some time. After upgrading to the latest version 24, the data encryption problem is repeatedly displayed