- JavaScript的超集
- JavaScript为动态语言
- typescript为静态语言
- typescript:JavaScript+类型支持
npm i -g typescript
tsc ts文件名称
npm i -g ts-node
ts-node ts文件名称
let age: number=18
js已有的类型
原始类型:number/string/boolean/null/undefined/symbol
对象类型:object
TS新增类型
联合类型
自定义类型(类型别名)
接口
元组
字面量
枚举
void
any
直接在前面加上:
如 :number
number[] :number类型数组
Array :字符串类型数组
联合类型:(number|string):表示里面类型的任意一种
类型别名:为任意类型起别名:
- type CustomArray=(number|string)
function add(num1:number,num2:number):number{
return num1+num2
}
// 基本数据类型
let aage: number =18
let aname: string ='myname'
let isLoading: boolean =false
// 复杂数据类型
// 数组类型 ,第一种写法
let numbers: number[] =[1,2,34,4]
// 数组类型,第二种写法
let arr: Array<number>=[1,3,4]
// 联合类型,数组中的数据即有number也有string
let strings:(number|string)[]=[1,'2222','blue']
// 类型别名
type customArray=(number|string)[]
// 使用类型别名来定义数组
let arr1: customArray=[1,2,'333']
// 等价于
let arr2: (number|string)[]=[1,2,'333']
//函数类型
// 为函数指定参数类型和返回值类型
function add(num1: number,num2: number): number{
return num1+num2
}
// 函数表达式情形
const add1=(num1:number,num2:number): number=>{
return num1+num2
}
console.log(add(1,3));
console.log(add1(1,3));
// 同时指定参数和返回值类型
const add2: (num1:number,num2:number)=>number=(num1,num2)=>{
return num1+num2
}
console.log(add2(1,2));
// void 返回值类型
function greet(name: string): void{
console.log('hello',name);
}
greet('peter')
// 可选参数,加上?
function mySlice(start?: number,end?: number): void{
console.log('start',start,'end',end);
}
mySlice()
mySlice(1)
mySlice(1,3)
// 对象类型
// // 属性类型写在一行中时,使用分号分割
// let person: {name: string;age: number;sayHi(): void}={
// name:'peter',
// age:18,
// sayHi() {
// },
// }
// 属性类型可以分行写,不用分号,函数可以使用给参数和返回值同时声明的类型
let person:{
name: string
age:number
sayHi:()=>void
}={
name:'peter',
age:18,
sayHi() {
},
}
// 对象的可选属性
// 可选属性与函数的可选参数写法一致
function myAxios(config:{url: string;method?: string}): void{
console.log(config);
}
myAxios({
url:'1234'
})
// 接口,类似类型别名
// 接口只可用于对象类型
// 而类型别名可用于所有类型
interface IPerson{
name: string
age: number
sayHi(): void
}
let person1: IPerson={
name:'peter',
age:19,
sayHi() {
},
}
// 接口继承
interface Point2D{
x: number
y: number
}
// Point3D 继承了Point2D
interface Point3D extends Point2D{
z: number
}
let point: Point3D={
x:1,
y:1,
z:1
}
// 元组,特殊的数组
// 明确规定只有两个值
let position: [number,number]=[23,114]
const link = document.getElementById('link') as HTMLAnchorElement
console.log(link.href);
// 字面量为number
let aname=18
// 字面量为'hello world'
const str: 'hello world'='hello world'
function changeDirection(direction :'up'|'down'|'left'|'right'){
console.log(direction);
}
changeDirection('down')
// enum虽然为枚举类型,但存储在计算机中的为自增的数字,默认从零自增
// 可以为enum的值赋予初始值
// enum Direction{'up'=1,'down','left','right'}
// function changeDirection(direction: Direction){
// console.log(direction);
// }
// // changeDirection(Direction.up) // 值为0
// // 值现在从1开始自增
// changeDirection(Direction.up) //1
// changeDirection(Direction.down) //2
// changeDirection(Direction.left) //3
// changeDirection(Direction.right) //4
// 2. 设置枚举的值为字符串
enum Direction{up='up',down='down',left='left',right='right'}
function changeDirection(direction: Direction){
console.log(direction);
}
// changeDirection(Direction.up) // 值为0
// 值现在从1开始自增
changeDirection(Direction.up) //up
changeDirection(Direction.down) //down
changeDirection(Direction.left) //left
changeDirection(Direction.right) //right
枚举是 TS 为数不多的非 JavaScript 类型级扩展(不仅仅是类型)的特性之一。
因为:其他类型仅仅被当做类型,而枚举不仅用作类型,还提供值(枚举成员都是有值的)。
也就是说,其他的类型会在编译为 JS 代码时自动移除。但是,枚举类型会被编译为 JS 代码!
console.log(typeof "hello world"); // string js的类型
// 当在类型上下文中使用typeof时,解析的是ts的类型
let p: {x:number,y:number}={
x:1,
y:2
}
function formatPoint(point: typeof p){
}
// 等价于
// function formatPoint(point: {x:number,y:number}){
// }
class Person{
age:number // 声明number类型
sex='男' // 赋初始值,类型推断
// 只读修饰符,默认值为666,只可以通过构造函数来修改初始值
readonly str:string="666"
// 构造函数
constructor(age:number,sex:string,str: string){
this.age=age
this.sex=sex
this.str=str
}
}
const p=new Person(19,'女','777')
class类中的方法类型注解与普通函数相同
class类可以extends(继承父类)和 implement(实现接口)
TS采用的是结构化类型系统,类型检查关注的是值所具有的形状,如果两个对象具有相同的形状,则认为他们属于同一类型
成员多的可以赋值给成员少的
类似于class,class于interface之间也可以兼容
- 成员多的可以赋值给成员少的
// 交叉类型 类似接口继承,用于将多个类型合并为一个类型
interface Person{
name:string
}
interface Contact{
phone:string
}
type PersonDetail =Person & Contact
let a:PersonDetail={
name:'123',
phone: '666'
}
// 交叉类型处理同名属性的兼容
interface A{
fn:(value: number)=> string
}
interface B{
fn:(value: string)=> string
}
// 交叉,
type C =A&B
let c:C={
// fn相当于
fn(value: number|string){
return ''
}
}
泛型是可以在保证类型安全的前提下,让函数与多种类型一起工作,从而实现复用,常用于:函数,接口,class
// 创建泛型函数
function id<Type>(value: Type): Type{
return value
}
// 以number类型调用
const num=id<number>(1)
// 以string类型调用
const str=id<string>('123')
// 简化泛型调用
const num1=id(10)
const str1=id('1234')
// 泛型约束,泛型只能打印值的本身,本身的属性无法获取(不知道何种类型,其拥有的属性也不同)
function id2<Type>(value: Type[]): Type[]{
// 数组一定有length属性,即使不是数组
console.log(value.length);
return value
}
interface Ilength{
length:number
}
// 添加约束,使传入的参数需要满足拥有length这个属性
function id<Type extends Ilength> (value:Type ) :Type{
return value
}
id('1233')
id(['1','2',3])
// 添加了两个类型变量,第二个类型变量用逗号分割
// keyof关键字接收一个对象类型,生成其键名称的联合类型
// 这里Key被约束,只能是Type的键中的联合类型
function getProp<Type,Key extends keyof Type>(obj:Type,key:Key){
return obj[key]
}
getProp({name:'jack',age:18},'name')
getProp({name:'jack',age:18},'name')
// 如果是基本类型,可以获取其包装类型的方法
getProp(18,'toFixed')
// 字符串类型,
// 这里的1代表索引,即'abc'[1]
getProp('abc',1)
// 泛型接口,在接口名称添加尖括号和类型
interface idFunc<Type>{
id:(value:Type)=>Type
ids:()=>Type[]
num:Type
}
let obj:idFunc<number>={
num: 100,
id(value){
return value
},
ids(){
return [1,2,3]
}
}
const arr:number[]=[1,2,3]
arr.forEach((value,index)=>{
})
// class GenericNumber{]
// defaultValue:NumberType
// add:(value:NumberType)=> NumberType
// }
// // 明确指定类型
// const myNum=new GenericNumber()
// myNum.defaultValue=10
// 当存在construct方法时,可以通过传递的参数推断处NumType
class GenericNumber<NumberType>{
defaultValue:NumberType
add:(value:NumberType)=> NumberType
constructor(value:NumberType){
this.defaultValue=value
}
}
// 不需要明确指定类型
const myNum=new GenericNumber(100)
myNum.defaultValue=10
// 无法确定属性中有多少类型时,可以使用索引签名类型
// 前置知识,js中的键的类型为string
interface AnyObject{
[key:string]:number
}
let anyObj={
a:1,
b:2
}
// 数组本身是一个接口,其键和对象不同,为number类型,即数组的索引
interface MyArray<Type>{
[key:number]:Type
}
const myArr=[1,2,3]
console.log(myArr[0]);
// 基于旧类型创建新类型,不能用于接口中
type TypeProps='a'|'b'|'c'
type Type1={a:number,b:number,c:number}
// 使用映射类型
type Type2={[key in TypeProps]:number}
// 根据对象类型创建新类型
type Type3={[key in keyof Type1]:string}