# 数据类型
在 Ts 中,定义数据类型之前需要,确定好数据的类型,这样有利于大型项目的维护,可以避免一些类型转换的时候,出现的一些错误。
在 js 基础上也增加了一些数据类型,原有类型:string, number, boolean, null, undefied, Symbol, Object, Array。
ts 新增的类型:tuple(元组), enum(枚举), any(任意类型), never, void。
# 1、基本数据类型
js 定义变量:
let age = 18;
ts 需要带上变量类型,定义好类型之后这个变量不能赋其它类型的值。
let age: number = 18;
age = "16" // 报错 类型不匹配
(1)字符串类型
let name: string = "Tom"
(2)数值类型
let age: number = 18;
age = null; // 正确
age = undefined; // 正确
(3)布尔值
let boo: boolean = true;
boo = null; // 正确
boo = undefined // 正确
(4)undefined,null
let n: null = null; // 只能写 null
n = undefined // 报错
let unde: undefined = undefined; // 只能是 undefined
unde = "hi" // 报错
(5)数组
数组也一样,元素类型固定,赋其它类型的值会报错,不会限制长度,语法:
方式一:let 数组名: 类型[] = [值1,值2];
let arr: string[] = ["apple","banana","pear"];
arr = [1,3,5]; // 报错
方式二:ler 数组名: Array<类型> = [值1,值2];
let arr: Array<string> = ["apple","banana","pear"]
arr = [1,3,5]; // 报错
(6)元组 在数组中无法定义数组值为不同的类型数据,这就是元组能解决的。
在数组中想保存不同类型的值怎么办?为了解决这个问题 ts 提供了元组的概念,特点:
- 指定元素个数
- 声明时,为每个元素定义类型
语法:let 元组名: [类型1,类型2,类型3] = [值1,值2,值3]
let car: [string,number,boolean] = ["BMW",2018,true]
car = ["BMW",2018,true,12] // 报错 长度不能超过
(7)any
比如我们不知道后端返回的数据类型是什么,这时候可以用 any 类型。
let text: any = "hello"
console.log(text) // "hello"
text = 123; // 正确
console.log(text) // 123
(8)void
像 C/C++ 一样代表没有类型,比如函数没有返回值,那么可以用 void。
语法:
function sayHi(): void{
console.log("hi!")
}
function sayHi(): void{ // 报错 返回类型(string)与声明类型(void)不一致
return "sayhi"
}
(9) never
never 代表不存在值的类型,常用于抛出异常或无心啊循环的函数返回值。 语法:
function text(): never{
throw new Error("异常")
}
(10)联合类型
一个变量可以是多个类型 语法: let 变量名: 类型1 | 类型2 = 值;
let num: number | string = "10";
num = 10; // 正确
num = "abc" // 正确
# 2、对象类型
对象类型我们先需要定义好结构最后在使用。
// 定义了一个对象类型
interface IPerson {
name: string,
age: number
}
// 使用
let p1: IPerson = {
name: "Tom",
age: 10
}
# 3、函数
ts 中函数的返回值也需要声明,没有返回值定义为 void 语法如下:
function sayHi(): string{
return "Hi!"
}
函数的形参也需要指定类型,比如:
function person(name: string, age: number): void{
console.log(name,age)
}
person("Tom",12)
TIP
实参和形参类型要保持一致 实参和形参数量要保持一致
有时候我们有一些可选参数,这个参数可以不赋值,在变量后面加个问好就可以了,可以有默认值,如果有默认值可以不写后面的问号:
function person(name: string, sex?:string, address: string = "earth"): void{
console.log(name,sex,address)
}
person("Tom") // Tom undefined earth
person("jerry","female") // jerry female earth
注意
可选参数必须写在最后
有时候还会有剩余参数情况,如果后一些不确定的参数,就可以用剩余参数:
function personName(name: string, ...names: string[]): void{
console.log(name,names)
}
personName("jeck","Tom","jerry") // jeck [ 'Tom', 'jerry' ]
函数声明
interface 也可以声明函数。
interface Isum {
(x: number, y: number, z?: number): number
}
const add = (x: number, y: number, z?: number): number =>{
if(typeof z === "number"){
return x + y + z
}else{
return x + y
}
}
let sum: Isum = add
# 4、类
面向对象的三大特性:封装、多态、继承。
在 ES5 中像面向对象编程需要 prototype 来完成,比如像这样:
function Person(name, age){
this.name = name;
this.age = age;
}
person.prototype.sayname = function(){
console.log(this.name)
}
在 ts 中提供了类的概念,上面的代码可以这样写,这与上面写的程序没什么区别,转换成 js 是跟上面的程序一样了,就是不同的写法而已。
class Person {
name: string;
age: number;
constructor(name: string, age: number){
this.name = name;
this.age = age;
}
sayName() {
console.log(this.name)
}
}
let pr = new Person("tom",16)
console.log(pr) // Person { name: 'tom', age: 16 }
pr.sayName() // 输出 tom 不是返回
# 5、枚举类型
表示固定的一些值,比如性别,男、女、未知。 枚举项一般是英文字母或数字,枚举值一般是数字。语法:
enum 枚举名{
枚举项1 = 枚举值1,
枚举项2 = 枚举值2,
}
举个例子:
enum sex{
male = 1,
female = 2,
unknown = 3
}
console.log(sex.male) // 0
console.log(sex[1]) // fmale
// 这样写也是合法的
enum sex{
male, // 默认值 0
female, // 默认值 1
unknown // 默认值 2
}
# 6、interface 接口
简单地说,提前定义对象的类型。比如有一个 Pesson
对象,我们提前约定好都有哪些属性,首先必须有 name
属性,而且必须是字符串类型。
接口定义使用 interface
关键字,接口的应用在于,协助我们日常开发,比如下面的例子,约定 name
为字符串之后,不能赋予其他值。
// 定义了一个 Person 接口
interface Person {
name: string;
age?: number; // 创建对象时, 此属性可有可无
readonly id: number; // 只读属性
}
// 使用接口初始化对象
let child: Person = {
name: "Tom",
age: 16,
id: 123,
}
// 报错 id 必须是 number 类型
let child: Person = {
name: "Tom",
id: "123"
}
# 7、函数高级用法
之前介绍过一点联合类型,这里介绍一下,联合类型与函数的结合使用。
function getLength(input: string | number): number {
const str = input as string; // 断言成 string 类型
if(str.length){
return str.length;
} else {
const number = input as number; // 断言成 number 类型
return number.toString().length;
}
}
# 8、泛型
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
function echo(arg) {
return arg
}
const result = echo(123)
我们传入了数字,但是返回了 any。
为了解决这个问题,我们使用泛型来解决。
function echo<T>(arg: T): T {
return arg
}
const result = echo(123)
// 泛型也可以传入多个值
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]]
}
const result = swap(['string', 123])
# 9、type 字面量
当有一些生命的类型比较长的时候,使用 type
可以简化代码。
两个变量的取值范围,限制在上面的四种字符串。
type Derections = 'up' | 'dowm' | 'left' | 'right'
const de1: Derections = 'down'
const de2: Derections = 'up'
也可以代替一些联合类型。
const StrOrNum = string | number
const str: StrOrNum = 'hello'
const num: StrOrNum = 123
# 10、声明文件
在 ts 文件中使用 js 写的库等工具时,可能会报错。为了解决这个问题,我们需要创建一个声明文件。
通常的格式为:xxx.d.ts
。比如使用 JQuery。
新建一个 jQuery.d.ts
的文件,写入以下内容:
declare var jQuery: (selector: string) => any
完成之后不会报错了。