对于一个不熟悉的事物一般我们会有三问,是什么?有什么用?怎么用?围绕这三问,来学习TypeScript。
1,TypeScript是什么
TypeScript 是 JavaScript 的一个超集,主要提供可选的静态类型,类和接口。
2,有什么用 ?
为了解决JavaScript类型系统的问题。
提高代码的可靠程度
说到这你可能会问 JavaScript类型系统有什么问题?
那我们先谈谈JavaScript的类型系统
分为七种语言类型:Underfined、Null、Boolean、String、Number、Object、Symbol。
JavaScript是一个弱类型语言(约束比较低)
弱类型就存在一个问题如:
- 在编程的时候不会告知开发者有问题,运行到该处时,才会报错。
- 会进行隐式转换,使功能不明确
var obj = {}
obj.foo()//运行的时候会报错,编码时没有提示
//会发生隐式转换
//如
function sum(x,y){
return x + y
}
console.log(sum(10,12))//22 相加
console.log(sum(10,'12')) //1012 会将数字型转换成字符串进行拼接
那也说说相对应的强类型的优势
- 错误更早暴露
- 代码更智能,编码更准确(如上,做加法的函数,不会变成字符串拼接)
- 利于重构
- 减少不必要的类型判断
怎么用 (画重点)
一,安装
yarn add typescript --dev //添加typescript依赖在项目中
安装完成后你可以在node_modules里.bin中看到tsc执行文件
二,基本使用
在其根目录创个getting.ts文件,内容如下
// 可以完全按照 JavaScript 标准语法编写代码
const hello = name =>{
console.log(`hello,${name}`)
}
hello('csz')
应行
yarn tsc getting.ts
会编译成一个getting.js文件
var hello = function (name) {
console.log("hello," + name);
};
hello('csz');
三,TypeScript配置文件
tsc不仅仅可以编译单个文件,还可以编译整个项目或者整个工程。
在编译整个项目前,我们需要先给整个项目创建一个TypeScript的配置文件。
yarn tsc --init// 初始化获取ts的配置文件,就像 yarn init 一样获取管理包
可看到teconfig.json文件
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
.
.
.
.
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
在这里面常用的属性“target”:这是说输出的是符合那个标准的
如:“target”: “es5”, 会将es6的输出是转换成符合es5的方式若target:es2015 其就不会将es6的方式转换成其它
四,TypeScript原始数据类型
/**
*原始数据类型
*/
const a: string = 'foobar'
const b: number = 100 //NaN Infinity
const c: boolean= true //false
// 在非严格模式(strictNullChecks)下,
// string, number, boolean 都可以为空
// const d: string = null
// const d: number = null
// const d: boolean = null
const e: void = undefined
const f: null = null
const g: undefined = undefined
五,TypeScript标准库
标准库就是内置对象多对应的声明,代码中使用内置对象就必须引用对应的标准库,否则TypeScript就会报错。如
// Symbol 是 ES2015(es6) 标准中定义的成员,
// 使用它的前提是必须确保有对应的 ES2015 标准库引用
// 也就是 tsconfig.json 中的 lib 选项必须包含 ES2015
// "lib": ["ES2015", "DOM"],TypeScript把BOM和DOM都归结到一个标准库中,为DOM
const t: symbol = Symbol()
在上述**const t: symbol = Symbol()**中,如果配置文件中“target"为es5,j就会提示错误,因为我们的symbol是es6中新增的类型,所以需要增加es6的基础库 lib。
六,TypeScript中文错误消息
yarn tsc --locale zh-CN
可以打印错误日志为中文的,优点就是像我这种英文差的人可以很快找到问题所在,缺点就是,可惜了一个学习英文的机会,还有就是百度问题的时候,不好找问题,一般社区都是英文的,哎。所以还是建议用英文的吧,太难了。
七,TypeScript作用域问题
不同文件中会有相同变量名的情况,此时TypeScript就会报出错误,重复定义变量。为解决这个办法,我们需要将变量放到不同的作用域或者使用export导出,这样文件就作为一个模块,模块是有单独的作用域的
八,TypeScript Object 类型
TypeScript中的object并不单独指对象类型,而是泛指所有的非原始类型,也就是对象、数组、函数。
// Object 类型
export {} // 确保跟其它示例没有成员冲突
// object 类型是指除了原始类型以外的其它类型
const foo: object = function () {} // [] // {} 可以接受对象、数组、函数
// 如果需要明确限制对象类型,则应该使用这种类型对象字面量的语法,或者是「接口」
//一一对应。
const obj: { foo: number, bar: string } = { foo: 123, bar: 'string' }
九,TypeScript 数组 类型
// 数组类型
export {} // 确保跟其它示例没有成员冲突
// 数组类型的两种表示方式
const arr1: Array<number> = [1, 2, 3]
const arr2: number[] = [1, 2, 3]
十,TypeScript 元组类型
元组就是数组的子类
// 元组(Tuple)
export {} // 确保跟其它示例没有成员冲突
const tuple: [number, string] = [18, 'zce']
// const age = tuple[0]
// const name = tuple[1]
const [age, name] = tuple
// ---------------------
const entries: [string, number][] = Object.entries({
foo: 123,
bar: 456
})
const [key, value] = entries[0]
// key => foo, value => 123
十一,TypeScript 枚举类型
枚举的作用是列举类型中包含的各个值。这是一种无序数结构,把键映射到值上。枚举可以理解为编译时键的固定访问对象,访问键时,TypeScript将检查指定的键是否存在。示例如下:
const post = {
title: 'Hello TypeScript',
content: 'TypeScript is a typed superset of JavaScript.',
status: PostStatus.Draft // 3 // 1 // 0
}
十二,TypeScript函数类型
函数的类型约束无外乎就是对函数的输入、输出进行类型限制,输入指的就是函数的参数,输出指的是函数的返回值。JavaScript中有两种函数声明方式,分别是函数声明和函数表达式。所以我们需要了解在这两种声明方式下,我们如何进行函数的类型约束。
// 函数类型
export {} // 确保跟其它示例没有成员冲突
function func1 (a: number, b: number = 10, ...rest: number[]): string {
return 'func1'
}
// a类型为数字类型,b类型为数字类型,...rest为参数默认值类型为数字,:string为函数返回值约束,如果没有...rest,则实参和形参个数必须相同
function func0 (a: number, b?: number = 10, ...rest: number[]): string {
return 'func1'
}
// 在参数声明冒号前加问号?,表示这个参数为可选值,无论可选参数或参数默认值,都只能出现在参数最后面
func1(100, 200)
func1(100)
func1(100, 200, 300)
十三、TypeScript任意类型
JavaScript本身是弱类型的语言,很多内置的API本身就支持接收任意类型的参数。
//可以是任意类型
function stringify (value: any) {
return JSON.stringify(value)
}
stringify('string')
stringify(100)
stringify(true)
any属于动态类型
let foo: any = 'string'
foo = 100
foo.bar()
// 语法上不会报错,TypeScript不会对any进行类型检查,any 类型是不安全的
十四,TypeScript隐式类型推断
在TypeScript中,如果我们没有通过类型注解取标记一个变量的类型,TypeScript会根据变量的使用情况去推断变量的类型。这种特性叫:隐式类型推断
// 隐式类型推断
export {} // 确保跟其它示例没有成员冲突
let age = 18 // number
// age = 'string' // 语法上会出现错误
// 如果TypeScript无法对变量进行类型推断,那TypeScript就会对这个变量的类型注解为any
let foo
foo = 100
foo = 'string' // 变量赋值任意类型的值,语法上都不会报错
今天就写到这把,之后再完善