Typescript
浏览器不支持ts代码,解析不了,要运行需要先把ts编译成js: tsc 文件名
一、基本类型
var flag:boolean = true // 布尔类型
var a:number = 123 // 数字类型(包括整型和浮点型)
var str:string = "hello" // 字符串类型
var str:any = "124" // 任意类型
var arr:number[] = [123, 23, 45] // 数组类型
var arr:Array<number> = [123, 23, 45] // 数组类型
var arr:[number, string, boolean] = [12, "hello", true] // 元组类型,属于数组的一种
// 枚举类型
enum Flag { success = 1, error = 0 }
var flag:Flag = Flag.success
console.log(flag) // 1
enum Color { red, blue, orange }
console.log(Color.red) // 0
console.log(Color.blue) // 1 - 打印下标索引
enum Colors { red, blue = 5, orange }
console.log(Color.red) // 0
console.log(Color.orange) // 6 - 打印下标索引
// null和undefined
var num:number | undefined // 定义未赋值就是undefined
console.log(num) // undefined
var num:number | null | undefined // 一个元素可能是number类型可能是null可能是undefined
// void类型 表示没有任何类型,一般用于定义方法时方法没有返回值
function run ():void { // 表示没有返回任何值
console.log(1111)
}
// never类型: 是其他类型(包括null和undefined)的子类型,代表从不会出现的值,这意味着声明never的变量只能被never类型所赋值
var str:undefined
str = undefined // str只能赋值为undefined,否则会报错,null同理
// object类型
function getObj(obj: object):object {
return {
name: 'haha',
age: 18
}
}
getObj({name: '小舞', age: 24}) // 正常
getObj(new String('123')) // 正常
getObj(String) // 正常
getObj('123') //报错
//接下来还有只读属性,有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性
// const 用于变量, readonly用于属性
interface Person {
readonly id: number;
name: string;
age?: number;
}
// 报错
viking.id = 9527
类型断言:告诉编译器,我知道我自己是什么类型,也知道自己在干什么
语法:
- <类型>变量名
- 值 as 类型
function getLength(str: number | string): number {
if ((<string>str).length) {
// 或者 return (<string>str).length
return (str as string).length
} else {
return str.toString().length
}
}
console.log(getLength(12345)) // 5
console.log(getLength('123456')) // 6
类型推断: TS会在没有明确指定类型的时候推断出一个类型
-
定义变量时赋值了,推断为对应的类型
-
定义变量时没有赋值,推断为any类型
let b = 9 // 推断为number类型 b="124" // 报错,不能将类型“string”分配给类型“number” let c c = "123" c = 233 // 推断为any类型,不会报错
二、函数
2.1 有返回值的函数
// 有返回值的函数
function getInfo(name: string, age: number): string {
return `${name} -- ${age}`
}
console.log(getInfo("唐三", 24))
console.log(getInfo("唐三")) // 报错
2.2 没有返回值的函数
// 没有返回值的函数
function getInfo ():void {
console.log(1111)
}
2.3 方法可选参数
// 方法可选参数: es5里方法的实参可以和行参不一样,但是TS中必须一样,如果不一样就要配置可选参数
function getInfo(name: string, age?: number): string {
return `${name} -- ${age ? age : '无'}`
}
console.log(getInfo("唐三")) // 不报错
// 注: 可选参数必须配置到参数的最后面
function getInfo(name?: string, age: number): string { // 报错
return `${name} -- ${age ? age : '无'}`
}
2.4函数默认值
function getInfo(name: string, age: number = 20): string {
return `${name} -- ${age ? age : '无'}`
}
console.log(getInfo("唐三", 30)) // 唐三 -- 30
三、Interface
// uuid后的问号代表非必传
// readonly代表只读属性,不能修改
interface Person {
readonly id: number;
name: string;
age?: number;
}
const keyArea: Person = {
name: '住院楼',
age: 25
}
在面向对象的世界中,一个类只能继承自另一个类,有时候不同的类之间有一些共同的特性,使用子类继承父类的方法很难来完成。这时候呢,我们就可以把这些特性提取成接口,然后使用implements来实现,提升其灵活性,约束各种概念上毫不相关的内容。
interface Button {
changeClick(): void;
}
interface Voice {
checkVoice(): void;
}
class Car implements Button {
changeClick() {
}
}
class Phone implements Button, Voice {
changeClick() {
}
checkVoice() {
}
}
interface Button {
changeClick(): void;
}
// 接口也可以继承
interface ButtonWithVoice extends Button {
checkVoice(): void;
}
class Phone implements ButtonWithVoice {
changeClick() {
}
checkVoice() {
}
}
四、类
- public:修饰的属性或方法是共有的。可以在任何地方调用到,默认的方法或属性都是共有的
- private:修饰的属性或方法是私有的。不能再声明它的外部调用
- protected:修饰的属性或方法是受保护的。与private类似,可以被子类调用
class Animal {
name: string;
constructor(name) {
this.name = name
}
private run() {
console.log(`${this.name} is running`)
}
}
const snake = new Animal('yanjing')
snake.run() // 属性“run”为私有属性,只能在类“Animal”中访问
class Dog extends Animal {
back() {
console.log(`${this.name} is backing`)
}
}
const dog = new Dog('wangchai')
dog.run() // 属性“run”为私有属性,只能在类“Animal”中访问
class Cat extends Animal {
constructor(name) {
super(name)
console.log(this.name)
}
run() {
console.log(`${this.name}`)
super.run() // 属性“run”为私有属性,只能在类“Animal”中访问
}
}
class Animal {
name: string;
constructor(name) {
this.name = name
}
protected run() {
console.log(`${this.name} is running`)
}
}
const snake = new Animal('yanjing')
snake.run() // 属性“run”受保护,只能在类“Animal”及其子类中访问
class Dog extends Animal {
back() {
console.log(`${this.name} is backing`)
}
}
const dog = new Dog('wangchai')
dog.run() // 属性“run”受保护,只能在类“Animal”及其子类中访问
class Cat extends Animal {
// 重写
constructor(name) {
super(name)
console.log(this.name)
}
run() {
console.log(`${this.name}`)
super.run() // 可以正常调用
}
}
class Animal {
// 只读属性
readonly name: string;
constructor(name) {
this.name = name
}
}
五、枚举
有些取值是在一定范围内的一系列常量,比如一周内的七天,从周一到周日就可以用枚举来表示。
enum Week {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
// 枚举都有一个默认值,从0开始
console.log(Week.Monday) // 0
// 枚举还做了一个反向映射,可以把这个枚举看成一个数组
console.log(Week[0]) // Monday
// 也可以给一个初始值,后面依次递增
enum Week {
Monday = 10,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
// 字符串枚举
enum Week {
Monday = 'Monday',
Tuesday = 'Tuesday',
Wednesday = 'Wednesday',
Thursday = 'Thursday',
Friday = 'Friday',
Saturday = 'Saturday',
Sunday = 'Sunday'
}
console.log(Week.Monday) // Monday
// 常量枚举, 能提升一定的性能,但并不是所有的enum都可以使用常量枚举
const enum Week {
Monday = 'Monday',
Tuesday = 'Tuesday',
Wednesday = 'Wednesday',
Thursday = 'Thursday',
Friday = 'Friday',
Saturday = 'Saturday',
Sunday = 'Sunday'
}
六、泛型
- 定义
定义函数、接口或类的时候,不预先指定具体类型,而是在使用的时候,再指定类型限制的一种特征。
// 此函数定义了传入什么类型的值,就返回什么类型的值
function echo<T>(arg: T): T {
return arg
}
// result是number类型
const result = echo(123)
- 约束泛型
interface IWithLength {
length: number
}
// 约束传入的arg必须含有length这个属性
function echoWidthLength<T extends IWithLength>(arg: T): T {
console.log(arg.length)
return arg
}
const str = echoWidthLength('str')
const obj = echoWidthLength({ length: 10 })
const arr = echoWidthLength([1, 2, 3])
const num = echoWidthLength(12) // 错误
七、Utility Types
属性 | 描述 |
---|---|
Partial | 把传入的类型变成可选的 |
Omit | 可以忽略传入类型某个属性 |
Required | 把传入的类型变成必须的 |
Readonly | 把传入的类型变成只读的 |
interface IPerson {
name: string
age: number
}
const person: IPerson = { name: '唐三', age: 24 }
type Ipartial = Partial<IPerson>
// name和age都不是必须的
const person1: Ipartial = { name: '唐三' }
type IOmit = Omit<IPerson, 'name'>
// 忽略name
const person2: IOmit = { age: 24 }