js简单易上手灵活多变,既是优点,也是缺点,会为上线的代码埋下隐患,简单举“栗”子:

let a;
a = 10;
a = '这是新值';

在js中这样书写是不会报错的,因为js不会对函数的参数类型和个数进行检测,但在项目中如果我们所需的值仅只为数字进行运算如下:

function sum(a, b){return a + b;
}
console.log(sum(12, 34)) // 46
console.log(sum(12, '34')) // 1234

显然无论我们传数字还是字符串,编辑和测试都不会出现编译错误,但是返回的数据结果却大不一样,这就导致我们在开发大型项目的过程中维护起来非常的头痛。而TS就是在js的基础上增加了类型的判断,所以一切支持js的地方都可以用ts,但值得注意的是,ts是不可直接被解析的,需要转换成js后才可以被解析。可能会有同学问为什么不直接整一套可解析的ts,是因为js就目前而言是不可代替的一门开发语言,在短时间之内添加一套辅助工具是最为这种的办法,也是为了兼容习惯了js的老程序猿。目前而言,ts不是必要的,但近几年一定会全面推广,所以快点学起来吧!
首先我们在正式使用ts之前,需要先配置好环境,如图:

首先我们先来认识一下TS基础类型

  • any => 任意类型,相当于放弃了类型校验,没有了ts的使用意义,不推荐使用
  • number => 数字类型
  • string => 字符串类型,包括字符串和模板字符串
  • boolean => 布尔类型,true 、false
  • [] => 数组类型(number[]、string[]、泛型: Array、Array)
  • [string,number,boolean] => 元组类型,必须一一对应
  • enum => 枚举类型
  • void => 表示方法返回空
  • null => 表示值缺失,空对象引用
  • undefined => 未定义
  • never => 其它类型,代表从不会出现的值
let a: number; // 当a的类型被设定为数字之后,那么a的值便只能是数字类型
a = 10;
// a = '字符串类型值'; // 此时a会报错
let a: string = '字符串类型值'; // 声明完变量直接对其进行赋值
let b = false; // 如果变量的声明和赋值是同步的,TS可以自动对变量的类型进行检测
// b = 123; // 此时b会报错,上方类型默认为b: boolean;

在书写方面呢,就像c++语言里的字面量方式,也可以给一个变量以多种类型,专业点讲叫联合类型,具体如下:

// 字面量赋值方式(字面量方式更类似于常量,只能赋值一次)
let a: 10;
a = 10;
// a = 11; // 此时a会报错,只能被赋值以10let b: 'male' | 'female';
b = 'male'
b = 'female'
// 同理可得 =>
let c: number | boolean; // 联合类型
c = 123;
c = false;

如果当我们没有给变量声明类型时,就会有隐式类型any,由于any类型想当与放弃了类型校验,所以既然我们要用ts,就最好不要用any类型。

let a = 10;
// a = '字符串类型值'; // 自动校验a的类型为number
let b;
b = false;
b = 123;
b = '345'; // 自动校验b的类型为any(隐式类型any)

但是如果我这里有一个变量我也不知道未来会具体给他什么样的值,那就用unknown,我们可以对比来看一下:

let a: string;
let b: any;
let c: unknown;
// any与unknown均可以赋值任意类型都不会报错,但他们的区别就在于any赋值给已有类型的变量不会报错,而unknown会作为一种未知类型而被限制
a = b;
c = b;
// a = c; // 因为a为string,c为unknown而类型校验不通过
b = 122 | '345' | false; // 各种类型赋值均不报错
c = 122 | '345' | false; // 各种类型赋值均不报错// unknown实际上是一个类型安全的any,不能直接赋值给其它变量,如果要赋值,则需先类型一致
// 方法一:
if(typeof c === "string") {a = c
}
// 方法二:类型断言
a = c as string; // 断言的两种书写方式
a = <string>c;

接下来,我们说一下函数的类型:

// 返回数字类型
function fun(): number {return 123;
}
// 返回多种类型
function fun(a: boolean): string | number {if(a) {return 521;} else{return '你失去了我';}
}
fun(true);
// 返回空类型
function fun(): void {console.log('浩浩爱茜茜');// return ;// return undefined;// return null;
}
// 没有返回值,报错的时候
function fun(): never{throw new Error('这里有一个错误');
}

说完了函数返回值我们再来说一下函数的参数:

// 设置函数结构的类型声明 (参数:类型)=> 返回值类型
let f = (a:number,b:number)=> number;
f = function fun(c1:number,c2:number): number{return 10;
}

有一种我们不会用到的类型那就是object,为什么这么说呢,在我们的js当中呢,花括号是一个对象,函数是一个对象…万物皆对象,所以在实际应用中,object并不会用到:

let a = {}; // 声明a是一个对象类型,并且可以指定对象中有哪些属性
let b = {name: string, age: number};
b = {name: '茜茜',age: 3};
// b = {naem: '浩浩', age: 3, mex: '男'}; // 属性只能一一对应
// 可以通过加?将属性变为非必要属性
let c = {name: string, age: number, mex?: string};
c = {name: '茜茜',age: 3};
c = {name: '浩浩', age: 3, mex: '男'}// 在开发过程中呢还可能存在的情况是对象中的属性是未知的,比如参数的不确定性,数量不确定,类型不确定,这种情况下则需要添加[propName: string]: any
let d = {name: string, [propName: string]: any}; // propName是自定义的,非固定
d = {name: '茜茜'};
d = {name: '浩浩', age: 3, mex: '男', text:'我的老婆是茜茜'}
// d = {age: 9, mex: '女', text:'我是无名氏'} // 缺少了必要属性name,所以报错

说完了对象,那就不得不说一下数组,上干货:

// 类型[] 或者 Array<类型>
let arr = number[];
arr = [1,2,3]
let arr1 = string[];
arr1 = ['1','2','3']
// tuple 元组 固定长度的数组
let arr2 = [string,string,number]
arr2 = ['1','2',3]

类似元组,我们再来看下枚举:

// enum 枚举 常用于选择范围有限的内容
enum Gender{male = 0, // 0->男female = 1 // 1->女
}
let i = {name: string,sex: Gender}; // 性别 男|女
i = {name: '茜茜',sex: Gender.female
}
console.log(i.sex === Gender.female) // true

上面我们有说到"|"的用法,那么现在来说一下’&'的使用:

// 在react语法中呢, || 表示或  &&  表示与 对应的在ts中用单一的 | + &
// let a: string & number // 实质上这种写法是不存在的,因为没有哪一种类型可以既是字符串又是数字
let obj: {name: string} & {age: number};
// obj = {name: '浩浩'} // 因为&表示同时满足所以单写一个属性会报错
obj = {name: '浩浩', age: 3}
// 那为什么不直接写let obj: {name: string,age:number}呢?这个&看上去似乎是多此一举,但是在大型的项目开发中会存在这种场景,两组数据有公共的部分,但是数据b包含了数据a的全部属性,这种情况下,我们就可以通过这种方式对已声明的a类型进行补充后使用

现在,我们来说下类型的别名使用:

// 我们要使用到type关键字
type myType = 1 | 2 | 3 | 4 | 5;
let a: myType
let b: myType
//b = 6 //因为myType里不包含6所以会报错
//类型别名呢,就相当于是一个类型的“公共组件”,用于声明公共的类型,可多处复用

与别名相类似的呢,还有接口:

// 接口主要是用来定义一个类结构,用来定义一个类中应该包含哪些属性和方法
// 同时也可以当成类型声明去使用
// -> interface
type myType{ // 描述一个对象的类型name: string,age: number
}
// type myType{ // 用type来声明对象类型如果重名是会报错的
//  sex: string,
// }
interface myInterface {name: string,age: number
}
interface myInterface { // 而接口是可以重名定义sex: string
}
let obj={ // 此时数据内容必须满足以上接口定义的全部结构name: '茜茜',age: 3,sex: '女'
}// 接口可以在定义类的时候去限制类的结构
// 接口中所有的属性不能有实际的值,只定义对象而不考虑实际值
// 接口中所有的方法都是抽象方法,定义类时去实现一个接口的要求规范interface myInter{name: string,fun(): void
}
class MyClass implements myInter{name: string;constructor(name:string){this.name = name;}fun(){console.log('这里是一个函数')}
}

对象的属性可以被任意修改,这导致了数据的不安全系数增高,例如:age:-38,人的年龄是不会出现负数,为了避免这种情况,就需要用到属性封装,这其中包含了ts的修饰符的知识点:

// public 修饰的属性可以在任意位置访问或修改 默认值 (你爸的钱,你可以继承花销,你儿子,你孙子都可以)
// private 私有属性,私有属性只能在类内部使用或修改(你爸的媳妇,你不能叫媳妇)但是可以通过添加方法使得私有属性可以被外部访问(但你可以叫妈)
// protected 受保护的属性,只能在当前类和子类中访问或修改,实例中不可以访问(基因里面的东西无法通过外界来更改,只有基因内部的突变)class Person{name: string;age: number;constructor(name:string,age:number){private this._name=name;private this._age=age;}//TS中属性存储器get name(){return this._name;}set name(val: string){this._name=val;}get age(){return this.age;}set age(val: string){if(val>=0){ // 通过函数方法来改变就可以增加对数据的限制this._age=val;}else {console.log('输入错误,请重新输入')}}
}
const pre=new Person(name:'浩浩',age: 4)
pre.age = 3
console.log(pre) // {name:'浩浩',age:3}

最后,我们来说一说泛型:

// 在定义函数或类时,会遇到类型不明确就可以使用泛型
function fun<T>(a:T):T{return a;
}
// 可以直接调用具有泛型的函数
let r=fun(10)// 不指定泛型,ts可以自动对类型进行推断
let r2=fun<string>('这是一串字符串') // 指定泛型// 泛型可以同时指定多个
function fun2<T,K>(a:T, b:K):T{console.log(b);return a;
}
fun2<number,string>(123,'345')// 泛型加接口约束
interface Inter{length: number;
}
function fun3<T extends Inter>(a:T): number{return a.length
}
class myClass<T>{name:T;constructor(name:T){this.name= name}
}
const MC = new myClass<string>('123')

基础内容告一段落,我们在这里说一下ts的编译指令

由于ts无法在浏览器里解析,所以我们没回书写完ts代码需要用tsc 文件名.ts 进行内容的转js,这就使得非常繁琐枯燥,为了更直观的查看我们编写的效果,可以使用tsc 文件名.ts -w来监听我们ts文件的编译,但只会对当前文件进行监听;这就显得很鸡肋,如果要自动监听全部的ts文件,则需要先使用tsc --init生成一个tsconfig.json的配置文件,再使用tsc -w即可监视所有文件
这里我们再说一下tsconfig.json文件内部配置的指令:

// 这里是tsconfig.json文件内部
/*
include用来指定那些ts文件需要被编译 ** -> 任意路径 * -> 任意文件
exclude用来指定那些ts文件不需要被编译 默认值是["node_modules","bower_components","jspm_packages"],仅为默认值时可以直接忽略exclude
*/
{"include": ['./src/**/*','其它任意路径']"exclude":[],"compilerOptions": { //重点 编译器的配置选项"target": "ES3", //ts被编译的es版本 esnext(最新版本)"module": "commonjs", //要使用的模块化规范"lib": [], // 指定项目中要用到的库 eg:["dom"]"outDir": "./",  // 指定编译后的文件输出所在目录"outFile": "./",  // 将编译后的代码合并到一个文件里 这里要注意的是如果代码里有模块化引入文件的内容需要对module配置对应的规范才能进行正常的编译"allowJs": true,  // 是否对js文件进行编译"checkJs": true,   // 是否检查js代码符合规范"removeComments": true, // 是否移除注释"noEmit": true, // 不生成编译后的文件"noEmitOnError": true, // 当发生错误时候不生成编译后的文件"strict": true, // 所有严格模式的总开关"alwaysStrict": true, // 用来设置编译后的文件是否采用严格模式"noImplicitAny": true,  // 禁止隐式的any类型"noImplicitThis": true,  // 禁止不明确类型的this"strictNullChecks": true, // 禁止空值}
}

生成package.json文件使用命令 npm init -y

良好编码习惯养成助手——TS相关推荐

  1. 良好的编码习惯 —— 5 个提高代码质量的技巧

    原文地址:Good Coding Practices – Five Tips to Enhance Code Quality 原文作者:Jay 译文出自:掘金翻译计划 本文永久链接:github.co ...

  2. 第十四期:5 个 JS 不良编码习惯,你占几个呢?

    在阅读JavaScript代码时,你是否有过这种感觉:你几乎不明白代码的作用?代码使用了很多 JavaScript 技巧?命名和编码风格太过随意? 这些都是不良编码习惯的征兆. 在阅读JavaScri ...

  3. [在线+源码]vue全家桶+Typescript开发一款习惯养成APP

    vue-ts-daily 基于Vue.js的2.5.13版本和TypeScript编写的模仿原生应用的WebApp. 源码地址 欢迎star 项目演示地址 建议直接添加到主屏幕(ios端体验差一些). ...

  4. 习惯养成android软件,六款有助于养成良好习惯的APP(安卓)

    原标题:六款有助于养成良好习惯的APP(安卓) 什么是习惯?灬无言理解为不去主动思考就去做的事情,如早起穿衣洗脸刷牙,坐哪路公交,边打开手机听着歌,也不会忘记在什么地方下车,转乘几号线地铁等等. 好习 ...

  5. 养成不断学习的好习惯_如何使用“小习惯”养成一致的学习习惯。

    养成不断学习的好习惯 If there's only one thing I could teach someone before they started learning to program, ...

  6. 程序员你为什么这么累【续】:编码习惯之日志建议

    转自:https://mp.weixin.qq.com/s?__biz=MzAxODcyNjEzNQ==&mid=2247484164&idx=1&sn=8351e9fb42e ...

  7. 出门问问×趁早|内测探索“序列猴子”大模型,联手打造“好习惯小助手”

    提到虚拟语音助手,你可能会想到siri--她可以随时随地帮你查地图.定闹钟.找餐厅.打电话.播放歌曲-- 但你有没有想到有一天,语音助手可以进化成"外接大脑"般的存在,ta有丰富多 ...

  8. 程序员你为什么这么累【续】:编码习惯之工具类规范

    导读: 程序员你为什么这么累? 我的编码习惯 - 接口定义 我的编码习惯 - Controller规范 我的编码习惯 - 日志建议 我的编码习惯 - 异常处理 我的编码习惯 - 参数校验和国际化规范 ...

  9. 我的编码习惯 —— API 接口定义

    工作中,少不了要定义各种接口,系统集成要定义接口,前后台掉调用也要定义接口.接口定义一定程度上能反应程序员的编程功底.列举一下工作中我发现大家容易出现的问题: 1. 返回格式不统一 同一个接口,有时候 ...

最新文章

  1. ubuntu 强制关机后 mysql无法启动
  2. 大数据时代分析师 Splunk助大数据落地
  3. Netflix Curator 使用 Zookeeper 编程
  4. Ajax请求Session超时的解决办法:拦截器 + 封装jquery的post方法
  5. Mysql bat脚本编写_第一次编写bat脚本
  6. 关闭(杀死)8080端口
  7. 字体 素材_4个网站,涵盖几乎所有素材,字体、设计、图片各种资源管够
  8. 雷达的正交波形设计matlab源码,雷达系统设计MATLAB仿真
  9. 【BZOJ4710】[JSOI2011]分特产(容斥)
  10. CF985E Pencils and Boxes
  11. 国内浏览器双核模式 默认切换chrome内核
  12. 【Matlab语音识别】声纹识别【含GUI源码 537期】
  13. 人力资源数据分析师前景_5-数据分析师前景怎么样
  14. 一个简单的多线程实现
  15. 免费通信时代何时真正到来?
  16. Java什么是对象?
  17. 通过yolov5训练自己的模型中遇到的一些问题及解决办法
  18. WF(Windows Workflow Foundation)
  19. LoRa模块网络组成和架构原理是怎样的?
  20. 在进行IBEACON定位时的可视化处理

热门文章

  1. 【第26篇】MobileNets:用于移动视觉应用的高效卷积神经网络
  2. VMware vSphere ESXi 6.7/7.0 定制安装盘(驱动或者SLIC)
  3. PM必备 | 4种基本素质和8大管理技能
  4. 华南主板bios怎么恢复出厂设置_最详细的主板bios设置图解教程bios设置指南史无前例...
  5. 前端对接打印机的一些经验总结
  6. CSS餐厅小游戏练习1~32关(附答案和链接)
  7. 不收费的电脑数据恢复软件EasyRecovery16
  8. android如何获取分屏区域的宽高,Android N获取屏幕高度的问题
  9. Animate.css动画演示
  10. blogs博客系统项目介绍