ts作为现在受很多开发者欢迎,原因之一就是使得代码更加严谨,减少错误率,在开发过程中我们学习一些基础知识也足够使用,这里我会分几个阶段来写基础和进阶部分,下面就先来看看入门级ts入门使用。
ts初体验
全局下载ts安装包
npm install typeScript -g
index.ts文件中编写代码
编译代码: tsc index.ts
指定编译文件输出目录
命令: tsc --outDir ./dist ./index.ts
指定编译的目标语言
tsc --outDir --target es6 ./dist ./inex.ts
监听模式 实时更新编译
tsc --outDir --watch --target es6 ./dist ./inex.ts
上面是一些关于ts的基础命令,小伙伴们可以尝试一下
但是有个问题,从命令中我们可以很明显看出是指定某个文件的,在开发过程中,有很多个ts文件,难道需要手动操作吗?当然不是,下面我们就全局配置
// tsconfig.ison
{
"compilerOptions": {
"outDir": "./dist",
"target": "es6",
"watch": true,
"skipDefaultLibCheck": true,
"noImplicitAny": true,
// "lib": ["es6"]
},
// ** : 所有目录(包括子目录)
// * : 所有文件 ,也可以指定类型文件 ["./src/**/*.ts]
"include": ["./src/**/*"]
}
类型系统
类型标注
类型检测
function test(a: number,b:number) {
return a+b
}
test(1,2)
// 上述中a后面的number就是我们的标注,对于参数a的类型标注
// 引入ts后会进行类型检查,若调用test函数,传入的两个参数有一个不是number类型就会系统提示
接口
定义与使用
interface Ip{
a: number,
b: string
}
let c:Ip = {a: 1, b: 2}
// 定义一个接口类型,命名为IP,C使用这个接口,此时系统会提示 “不能将类型“number”分配给类型‘string’”
可选属性
interface Ip{
...
c?: boolean,
}
let c:Ip = {a: 1, b: 2}
这里不定义c也不会报错,问号代码可传可不传
只读属性
interface Ip{
...
readonly d: number
}
let c:Ip = {a: 1, b: 2,d: 5}
// readonly代表只读,只定义时被赋值,后期不可进行更改
任意属性
interface Ip{
...
name: any
}
let c:Ip = {a: 1, b: 2,d: 5,name: [1,2,3]}
//当给类型定义为any时就代表他可以是任意属性,无论是传数组、还是字符串等都可以
函数类型接口
interface IFunc {
(a: string,b:string): string
}
let fnc: IFunc = function (a: string,b:string):string {
return a
}
接口合并
interface people {
name:string,
age: number,
}
interface people {
class: number,
hobby?: string
}
let p: people = Object.assign({},{name: 'mike',age: 18},{class:3}):
}
// 此处需要注意,tsconfig文件中配置的转换类型要为es6,否则会报找不到Object下面的assgin,这里利用es6中合并对象的方法
// 如果合并的接口存在同名的非函数成员,则必须保证他们类型一致,否则编译报错,这里涉及到函数重载
高级类型特性
联合类型
function a(name: string | number) {
return a
}
a('kiki')
// 函数a的参数类型可以为字符串或者数字
交叉类型
interface o1 {
x: number;
y: string
}
interface o2 {
z: number
}
let o: o1 & o2 = Object.assign({},{x:1,y: 'jkjk'},{z: 2})
字面量类型
function setAttr(ele: Element,dir: 'left' | 'top' | 'bottom' | 'right') {
...
}
setAttr(div,'left')
类型别名
interface callback {
a: number,
b: number
}
type callBack = { a: number,b: number }
interface与type的区别
interface
--只能描述object/class/function的类型
--同名的interface会自动合并
type
--可以描述任意类型
--不能同名
函数
函数类型标注
函数声明式
function c1(a:string): string {
return a
}
函数表达式标注
let c2:(a:string) => string = function(a: string) {
return a
}
默认参数
function sort(items:Array<array>,order = 'desc') {
// 参数默认值
}
sort([1,2,3]) // 默认值是可选参数,不传则默认值; 设置了默认参数的值可以根据值自动推导类型
参数-联合类型
function sort(items:Array<array>,order: 'desc' | 'asc' = 'desc') {
// 参数默认值
}
sort([1,2,3],'asc')
剩余参数
function merge(target: any, ...others: Array<any>) {
return others.assign(target,{...others})
}
let newObj = merge({x:1},{y: 2},{z: 3})
// 剩余参数是一个数组,标注的时候注意类型为array
普通函数与箭头函数中的this
// 普通函数
interface T {
a: number,
fn: (x:number) => void
}
let obj: T = {
a: 1,
fn(x: number,this: T) {
// ...
}
}
obj.fn(1) // this 不占据实际位置
// 箭头函数
let obj: T = {
a: 1,
fn(x: number,this: T) {
return () => {
}
}
}
// 箭头函数 this是固定 一旦声明就固定
函数重载
可用于相同函数实现不同功能,利用重载定义不同功能的函数
以上为ts的基础入门知识,下篇会讲解进阶部分