下面让我们一起走进TS世界
写在前面
先来了解下,什么是TypeScript?TypeScript是一种由微软开发的支持ES6标准的编程语言,它是JavaScript类型的超集,它可以编译成纯JavaScript。TypeScript可以在任何浏览器、任何计算机、任何操作系统上运行,并且是开源的。
为什么TypeScript越来越受到前端开发的厚爱呢,看了下面TypeScript入门知识介绍,你就明白了。
1、基本类型和Symbols
因typescript支持es6标准,所以es6中规定的语法我们都可以使用。关于此部分,后面不做过多赘述。
我们可以使用冒号“:”来为声明的变量或者函数指定类型,指定类型后,在后续使用中就不能为其设置其他类型的值,否则编译会提示错误,如下例子:
let str: string = 'i am string' // 字符串
str = 13 // 上面声明str为string类型,此处赋值number类型,会报错
// 另外typescript支持模板字符串,所以我们可以如下书写
let str2 = `hello world ${str}`
console.log(str2) // hello world i am string
// 其他类型声明如下let num: number = 10 // 数字
let bool: boolean = true // 布尔
let arr1: (number|string)[] = [1, 2, 'a', 'b'] // 数组,并指定数组元素类型
let arr2: Array<number|string> = [1, 2, 'a', 'b']复制代码
还有其他几种类型如下:
tuple: 元组,表示已知元素的数量和类型的数组,
any:代表任何类型,如果不确定是什么类型可以声明这个
void:void表示没有类型,当一个函数没有返回值,我们通常会设置为void,声明一个void类型的变量没有什么大用,因为你只能为它赋予undefined和null
undefined: undefined
null: null
例子如下:
// 元组let arr: [string, number]
arr = ['str', 10] // okarr = [10, 'str'] // error, 和声明的不一样
// 如果访问越界,比如访问arr[2], 则会使用联合类型代替,上面例子就是<string|number>
arr[2] = true // error, 不是联合类型
arr[2] = 30 //ok, 是联合类型
let a: any = 'hello world'
a = 10 // ok,不会提示错误
function fn1(): void {
console.log('this is a message')
}
let u: undefined = undefined
let n: null = null// 返回never的函数必须存在无法到达的终点
function fn2(err: string): never {
throw new Error(err)
}复制代码
关于Symbols
Symbols是ES6新增的一种数据类型,symbols类型的值是根据symbols构造函数创建的.
Symbols是不可改变且唯一的,symbols还有一个API方法,具体可以去官网了解,例子如下:
let sym1 = new symbol()
let sym2 = new symbol()
console.log(sym1 === sym2) // false复制代码
2、函数
关于函数
箭头函数就不介绍了,肯定可以使用箭头函数的
我们可以为函数参数和返回值指定类型,
默认参数:用’=’为函数参数指定默认值,带有默认值的参数必须写在参数最后
可选参数:用‘?’为函数参数指定为可选参数,可选参数必须写在必选参数后面
剩余参数: 如果不知道要传的参数总个数,可以使用…来获取剩余所有参数数组,类似js中的arguments
function fn1(a: number, b: number, c: number): number {
return a + b + c
}
console.log(fn1(1, 2, 3)) // 6
// 默认参数
function fn2(a: number, b: number, c: number = 3): number {
return a + b + c //c有默认值,不传则默认为3
}
console.log(fn2(1, 2)) // 6
// 可选参数
function fn3(a: number, b?: number, c: number = 3) {
console.log(a)
console.log(b) //b为可选参数不传则默认为undefined console.log(c)
}
fn3(1)
// 1
// undefined
// 3
// 剩余参数
function fn4(a: string, ...c: string[]): void {
console.log(a + c.join(' '))
}
fn4('hello', 'tyscript', 'hello', 'world')
// hellotypescript hello world复制代码
3、接口(interface)
TypeScript的核心原则之一是对值所具有的结构进行类型检查。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。
在TS中使用interface关键字来声明一个接口,废话少说,先来看一个简单的接口例子:
// 这个接口的意思就是说使用接口者必须传一个name属性,且为string
interface StudentObj {
name: string
}
function student (params: StudentObj) {
console.log(params.name)
}
let stuOpt1 = {name: 'laowang'}
let stuOpt2 = {name: 1}
student(stuOpt1) // laowang
student(stuOpt1) // error, name必须为string
//可选属性: 可以使用?来声明接口的可选属性
interface StuOpt {
name?: string;
age: number
}
function createStu(params: StuOpt): void {
console.log(params.name)
console.log(params.age)
}
createStu({age: 18}) // undefined 18
// 只读属性:假如一些对象的属性值,只可以在刚刚创建对象的时候修改属性值,可以使用readonly设置只读属性。
interface StuOpt {
name: string;
readonly age: number
}
let stu1: StuOpt = {name: 'laowang', age: 18}
stu1.name = 'xiaoming' // ok
stu1.age = 20 // error
// 当然还有一个ReadonlyArray属性,确保数组创建后,不能再被修改
let arr: number[] = [1, 2, 3]
let newArr: ReadonlyArray<number> = arr
newArr.push(5) // error
newArr[0] = 10 // error复制代码
针对readonly和const的区别,可以这么理解,如果是一个变量使用const, 如果是一个属性使用readonly
函数类型接口:如果接口是一个函数类型,那么我们可以定义一个定义签名,类似一个只有参数列表和返回值的类型的函数定义,例子如下:
interface StuFunc {
(name: string, age: number): string
}
let stu1: StuFunc = function(name: string, age: number): string {
return `my name is ${name}, age ${age}`
}复制代码
类类型接口: TS也可以强制一个类去符合某种接口,使用implements,例子如下:
interface StuOpt {
name: string;
sayHi(msg: string): string
}
class stu implements StuOpt {
name: 'laowang';
sayHi(msg: string): string {
return msg
};
constructor() {}
}
// 当一个接口对类进行类型检查时,只会对其实例部分进行类型检查,不会对静态部分进行类型检查,constructor存在于类的静态部分复制代码
继承接口:继承接口和类的继承相似,可以将一个接口复制到另一个接口,方便接口的分割和复用,使用extends关键字
interface StuOpt1 {
name: string
}
interface StuOpt2 extends StuOpt1 {
age: number
}
let stu1 = <StuOpt2>{}
stu1.name = 'laowang'
stu1.age = 18
// 一个接口也可以继承多个接口
interface StuOpt3 {
gender: string
}
interface StuOpt4 extends StuOpt1, StuOpt3 {
language: string
}复制代码
还有一点需要注意的是:当接口继承类类型,会继承类的所有成员,但是不继承其具体实现,接口同样会继承private和protected成员,也就是说,如果一个接口继承了拥有私有或者受保护的成员时,这个接口就只能被这个类或它的子类实现
个人学习总结,有错误之处欢迎指出。
未完待续......