Typescript - why-what-how?

更好的开发体验
在开发中解决 js 解决不了的问题

  1. 使用不存在的函数、变量、成员
  2. 类型错误:把一个不确定的类型,当作一个确定的类型使用
  3. 使用 undefined 或者 null 的成员 Uncaught TypeError: Cannot read property xxx of null, 熟悉嘛?
  4. ...

JavaScript

  • 弱类型:变量可以随时更改类型。
var a;
var a = 10;
var a = 'string';

在声明变量的时候, 我们就没有给变量 a 一个确定的类型,所以在开发中,a 的类型可以任意改变,而事实上真的需要这样做吗(或者说允许一个变量可以随意更改一个类型真的是好事吗)?

var width = 100;
// 省略三千行代码
width = '200px';
//再省略三千行代码
document.getElementById('xxx').style.width = ???

我们在投入业务开发中的时候, 更多的关注点在于业务,而不是语言特性,所以在某个时间节点,我也不知道width 被重新赋值了多少次,我现在想用width 这个变量的时候,width 究竟是个什么?数字还是字符串? 要不要加上"px", 不回去看代码九成不知道。

如果有一个东西,能够在我第二次将 width 变成一个字符串的时候, 提醒我, 你不能这么干, 这个width原来是一个数字,你写成了字符串,后面会出现混乱!

  • 解释型语言:错误发生在运行时。
    代码运行是解释一行执行一行,没有传统语言的编译过程,所以无法在执行之前发现错误, 但是写代码的是人,人是不可能避免出现错误的。
  • Javascript本身的语言特性, 它并不适合做大型项目。

所以在前端开发中,大部分时间都在排错😂。

TypeScript

TypeScriptJS 的一个超集,是一个可选的,静态的类型系统。TS 不是一门新的语言,js 代码修改后缀为 ts 一样可以正常执行,超集的意思是: 男人、女人、小孩、大人,人是超集。只要是人, 都在这个集合里面。

TypeScript 可以解决上述问题。它会对代码中的所有标识符(变量、函数、参数、返回值等)进行类型检查和推导。从而减少不必要的错误发生,换言之,开发过程中使用 ts比 使用js拥有更强的生产力。

2012 年由微软发布并开源。

TS 代码不能直接运行在各个环境中

TS 增加了一些特殊的语法来进行类型检查,所以,无论是浏览器还是Node 环境,都不能识别这些新增加的语法。需要通过 TSC (TypeScript Compiler )编译之后执行。编译之后是纯粹的Javascript代码

开始吧

全局安装 typescript 和 编译器 tsc,新建一个 ts 文件, 写两行代码:



现在你还会因为类型错误浪费大量时间查错而烦恼吗?

function getNumber():number{
  return 1
}
var width:number = 100;

再写两行代码, ts 与 js 明显的不同就是,定义了变量、函数返回值的类型。如果返回的类型不是期望的类型,编辑器首先会提示报错,如果对此置之不理,使用 tsc 编译的时候会报错。这就和强类型语言很像了,语法不对,编译都不能通过。

function getNumber() {
    return 1;
}
var width = 100;

使用tsc src/index/ts编译之后的代码与正常的 js 一样。

注意
默认情况下, ts 会作出如下假设:

  1. 假设当前执行环境是 dom (浏览器环境)
  2. 代码中如果没有模块化语句(import、export),便认为此代码全局执行
  3. tsc 编译的目标代码是 es3

有两种方式更改上述默认设置:

  1. 使用 tsc 命令的时候加上参数
  2. 使用配置文件更改编译选项,配置文件之后,直接使用 tsc 就可以了, 如果后面指定了文件夹,那么会忽略掉配置文件。

对变量以及函数的约束

// 约束变量
let name:string = "mike";
let age:number = 18;

// 约束函数
function add (a:number, b:number):number{
  return a + b;
}
// 参数以及返回值的约束,如果传参和返回值类型不符合约束,会直接提示报错
let number:number = add(1,2);

在很多场景下, ts 可以自行完成对某些变量类型的推导:

function add (a:number, b:number){
  return a + b;
}

此函数返回的一定是一个number, 这是确定的:



在每一个声明,赋值的地方,都会有类型检查。

let a; // 这是一个 any 类型, 即任意类型, ts 不对 any 类型作类型检查

基本类型约束

  1. number
  2. string
  3. boolean
  4. null 和 undefined

这两个比较特殊, 它俩不用作类型约束, 是所有类型的子类型,一个被定义为某个确定类型的变量可以被赋值为 null 和 undefined。
但是这样会引发问题:

let str:string = undefined;
str.toUpperCase() ????

是不是会出问题? 所以对于这个情况,一般是不允许这么做的,我们可以在编译选项中设置 严格的空类型检查 "strictNullChecks": true

复杂类型约束

  1. 数组
// 约束数组
let arr:number[];
let arr: Array<number>[];
  1. 对象
let obj:object;
// obj 只能被赋值为一个对象,但是无法深入定制对象里面属性的类型
  1. 联合类型
    有时候,比如一个用户的名字, 它可能是一个字符串,也可能还没有填写, 这时候是可以为 undefined 的,此时可以使用联合类型
let name:string | undefined = undefined;


ts 不确定类型的时候,你想象的这个类型对应的方法,不会给你智能提示。所以这里经过了判断,如果names 的是string 类型, 才会给出对应的智能提示, 因为代码执行, 如果进了这个判断, 这个names 一定是string类型了。这也提醒我们, 如果在用 ts 开发过程中,你想使用某个方法却没有智能提示的时候, 就要小心了, 类型可能出问题了。

  1. void 类型: 通常用于约束函数的返回值, 表示不返回任何值。
funtion f():void{
  return 1;
}
// 说一不二的 ts, 如果规定了此函数不返回值, 如果返回了也会报错。
  1. never : 通常用来约束函数的返回值, 表示这个函数永远不可能结束
    函数结束的定义式最后一行代码执行完毕
function do():never{
  while(true){}
}
  1. 字面量约束

    这意思很清楚了,将变量a以字符串“A”约束,从此a只能是“A”
let sex: "男" | "女";

let user: {
  name: string,
  sex: "男" | "女",
  age: number
}
// 注意 user 后面不是等号, 不是赋值, 这里是使用字面量的形式约束user
  1. 元组约束
var tuple: [string, number]

约束 tuple 必须是一个数组, 数组有且只能有两项, 第一项为字符串, 第二项为数字。

  1. any: 此类型可绕过类型检查。可以赋值为任意类型。

类型别名

 type User =  {
  name: string,
  sex: 'male' | 'female',
  age: number
}
// 函数返回一个 User 类型的数组。
function getUsers ():User[]{
  return []
}

函数相关约束

这里有个函数, 接收两个参数。 如果这两个参数都是数字, 返回二者的乘积, 如果二者都是字符串, 拼接返回。

function combine (a: number|string, b: number|string):number|string{
  if(typeof a === 'number' && typeof b === 'number'){
    return a * b;
  }
  if(typeof a === 'string' && typeof b === 'string'){
    return a + b;
  }
  throw "a and b should be a same type";
}
let res = combine(1, 2)


我传入了两个数字,很明显返回值肯定是一个number, 但是系统提示res 可能是 string 或者number。 这是不符合我们要求的。 我们希望, 传两个相同类型的值做出对应的确定的回应。

function combine(a: number, b:number):number;
function combine(a: string, b:string):string;
function combine (a: number|string, b:number|string) :number|string{
  if(typeof a === 'number' && typeof b === 'number'){
    return a * b;
  }
  if(typeof a === 'string' && typeof b === 'string'){
    return a + b;
  }
  throw "a and b should be a same type";
}

let res = combine(1, 2)

这下确定了!我们使用声明式的约束,明确指出,同number返回number。这类似于 Java 的重载。

可选参数 & 默认参数

function sum(a: number, b: number = 0, c?: number){
  return c ? a + b + c : a + b;
}

在参数名之后,添加一个 ?,表示该参数可选。
在参数声明完成后, 可以为参数添加默认值:b: number = 0

枚举

enum Gender {
  male = "男",
  female = "女"
  // 逻辑名称 = 真实值 
}
  • 数字类型的枚举,默认会自增,如果不赋值, 默认从0开始自增。
enum Level {
    normal = 1,
    vip, // 2
    svip, // 3
    s_svip // 4
}

================================================

(前端知识博大精深,仅作为自己备忘,不作为教程 )

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350