ts中文官网:https://www.tslang.cn/docs/handbook/jsx.html
安装 运行编译
tsc -v // 没有就安装 Version 4.7.3
sudo npm install typescript -g // mac环境
tsc test.ts// 编译成js给浏览器识别
tsc init // 项目中 创建tsconfig.js
基于js 范围的话 ts > es6 > es5 > js
组合类型
类型断言:“尖括号”语法和as语法
如:
let someValue: any = "777";
let strLength: number = (<string>someValue).length;
let strLength: number = (someValue as string).length;
// 定义组合数组的两种方式
let numStrArr: (number | string)[] = [1, 2, 'a', 'b']
let boolStrArr: Array<boolean | string> = [true, true, 'a']
但是上面这个写着好累,所以用元祖比较好,在需要多个类型的情况
// 数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象。就不需要用组合类型了
// 定义一对值分别为string和number类型的元组 Tuple
let tuples: [string, number]
tuples = ['name', 20] // 其他就会报错 顺序必须一致,数组顺序可以不一致
tuples[3] = 'world' // 不能将类型“"world"”分配给类型“undefined”。v4版本
// v3版本 当访问一个越界元素,会使用联合类型替代,字符串可以赋值给(string | number)类型,但是不能赋予布尔值或者其他
枚举类型 enum
// const方式定义变量,只是限制了变量的引用不可变,但是对象的属性值仍然是可以改变的
// readonly ReadonlyArray 是修饰属性的
// 枚举 申明固定不变的对象
// 通过下标的方式来取值或者通过值反向取到下标 数字美剧
enum Color { Red = 1, Green, Blue } // 默认情况下,从0开始为元素编号。也可以自己设置比如1
let c: Color = Color.Blue
// 字符串枚举 得到下标 c['Red']
enum Color { Red = 'Red', Green = 'Green', Blue = 'Blue' }
别名在JSX中不能写成:xxx 得写成as xxx
还有Unknown,any,never,viod,in,infer, keyof等,当然几乎js有的ts也有
函数 function
// 如下:参数虽然不固定,但是每个都必须为number类型,返回值也是number
function sum2(...arg: number[]): number {
return arg.reduce(function(sum, val) {
return sum + val
}, 0)
}
// ?: 可选参数函数
// 如下:如果传一个参数获取值,传两个参数就是设置值
let obj = {}
function fn(key: string, val?: any): any {
if(val) {
obj[key] = val
} else {
return obj[key]
}
}
类 class 继承 extends
abstract 抽象类关键字 子类必须定义方法
// 对象在ts中不可动态添加属性
// class也不可动态添加属性,必须要定义好实例属性,才能赋值
// 函数定义形参类型,用来约束调用,私有属性只在此类可以访问
class Animal {
private static color: string = 'red'// 私有静态属性 类里可以Animal.color访问
public name: string// 公开 属性方法都能在类的外面调用
public status?:string// 可选 子类不是一定要这个
protected sex: string// protected可以在子类中访问,实例访问不到
static age: number = 20 // 静态属性 直接通过类访问
public readonly read: boolean // readonly只读修饰符只允许赋值一次
constructor(name:string,sex: string) {
// 外部入参
this.name = name
this.sex = sex
// this.age = age// 改为访问静态成员“Animal.age”
}
// 外部访问 a.move()
move(): void {
console.log(this.name,this.sex)
console.log(Animal.color,Animal.age)
}
// 外部访问 Animal.eat()
static eat(): void {
console.log(this.name)
console.log(Animal.color,Animal.age)
}
}
let a: Animal = new Animal('肥羊','女')// 动物实例a
class Cat extends Animal {
constructor(name: string,sex:string) {
super(name,sex)// 绑定cat 改变this指向
}
move() {
console.log('移动去')// 子类可以重写父类的方法
super.move()
}
}
模块
module X { 相当于现在推荐的写法 namespace X {)
// export导出
export const numberRegexp = /^[0-9]+$/;
export class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.length === 5 && numberRegexp.test(s);
}
}
// 或者
export { ZipCodeValidator };
export { ZipCodeValidator as mainValidator };// 别名
declare module "url" {
export interface Url {
protocol?: string;
hostname?: string;
pathname?: string;
}
export function parse(
urlStr: string,
parseQueryString?,
slashesDenoteHost?
): Url;
}
接口 interface
接口是对类的行为进行约束 接口只声明和类型定义,类是代码复用
interface用来 约束 属性,函数,变量,类class
// 对象 接口可以用来设定或限制对象里面每个属性的类型
interface IPerson {
name?:string;// 可选属性
date:string;
sex:string;
action():void;
[propName:string]: any; //任意属性 包括可选和必选属性
};
let obj : IPerson = {必须和接口一致}
// 类和接口建立关联,靠implements建立 而不是:
interface UserInterface {
name: string;
say(): void
}
class User implements UserInterface {
constructor(public name: string) {}
say(): void {}
}
interface Ifon {
readonly name: number;// 不可改变
readonly age: number;
color?: string;
width?: number;
}
// 函数类型的定义 输入类型,输出类型
//接口在函数中运用
interface IFn {
(source: string, sub: string): boolean
}
let fn: IFn = function(src: string, sub: string):boolean {
// 函数的参数名不需要与接口里定义的名字相匹配 :boolean可不写
return true
}
泛型 Generics
泛型是指在定义函数、接口或类的时候,不预先指定具体的类型 使用的时候再指定类型的一种特性
// 泛型指基础类型或者对象比如Date
// 泛型约束数组
type T = (Date|number)//这里固定了2种 T表示任何类型 常用有T K V E Y N U
let arr: Array<T> = [678, new Date()]
// 泛型约束函数function 任意类型的返回入参 保持统一,和any不一样
function fn<T> (...arg: T[]): T[] {
return arg
}
// 结合接口 约束函数
interface Ifn {
<T>(a:T,b:T):boolean
};
let fn:Ifn = function<T>(s1:T,s2:T):boolean{
return s1==s2
};
fn(1,2)// 调用
// 泛型约束类class 类中定义泛型,泛型适用于多个类型
class Animals<T> {
private data = {}
n:T
set(key: string, val: T): void {
this.data[key] = val
this.n = val;
}
get(key: string): T {
return this.data[key]
}
add(n1:T):T{
return n1
}
}
var an = new Animals<string>()
function sum<T>(n1:T,n2:T):T[] {
return [n1,n2]
}
sum<string>('1','2');
sum(3,5) //类型推断
//多个类型
function multi<N, S>(sum: [N, S]): [S, N] {
return [sum[1], sum[0]];
}
multi<number,string>([1, 'one']);
装饰器 @fn
启用experimentalDecorators
tsc --target ES5 --experimentalDecorators
// 装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。
// 装饰器的语法是在要装饰的类/属性/方法前面使用@符号调用函数
// 装饰器函数 参数:target(类的prototype,static静态是类的构造函数),name(名字)还有少用的descriptor 也许会被返回
function fn(target: any) {
console.log(target)
target.num = 100
}
// 装饰器工厂
function fnbox(type: any) { // 这是一个装饰器工厂
console.log(type) // 1/2
return function(target: any) { // 这是装饰器
if (type === 1) {
target.name = '肥羊好'
} else if (type === 2) {
target.name = '哈哈哈'
}
}
}
// 装饰器组合
@f @g x
// 类装饰器 类构造函数监视,修改或替换类定义
@fn
@fnbox(1)// 装饰器会自动调用函数,把类传递过去
class Animals {
constructor() {
}
}
// 执行顺序:
// 方法和属性:@前面的先执行
// 方法和参数:参数先执行
// 参数:最后一个参数先执行
// 类:最后执行
@One()
class Hello {
@Five()
hello: string
@Two()
haha( @Three() p1: string, @Four() p2: string ) {
console.log(p1, p2)
}
}
组合 函数 类 接口 泛型
还有好多种组合。
//函数表达式
let es5fn = function<U>(n1:U,n2:U):U[] {
return [n1,n2]
}
//ES6
let es6fn = <U>(n1:U,n2:U):U[] =>[n1,n2];
s6<string>('1','2');
//泛型的约束
interface ILengthNum {
length:number;
}
function fn<T extends ILengthNum>(str:T):number {
return str.length
};
fn('123');
// 2个接口 声音不通
interface ISing {
singfn();// 唱歌 接口
}
interface Ispeak {
singfn1(s:string):void;// 说话 接口
}
//开关接口 继承 唱歌 说话 接口
interface ILight extends ISing,Ispeak{
lightOn();// 开关
lightOff();
}
//鹦鹉 鹦鹉的种类:1、和尚鹦鹉2、虎皮鹦鹉3、金刚鹦鹉
class Parrot {
name:string
}
enum Color {
Green, Red
}
//和尚鹦鹉 绿色,红色继承于鹦鹉 extends 能唱歌能说话implements
class Monkparakeet<T extends Color> extends Parrot implements ISing, Ispeak{
private color: Color; //私有属性
name:string
constructor(c:T){
super();
this.color = c;
}
singfn(){...};// 唱歌
singfn1(){...};// 说话
}
//录音机被3个接口约束
class Recorder implements ILight {
singfn(){...};// 唱歌
singfn1(){...};// 说话
lightOn(){...};// 开关
lightOff(){...};
}
//接口继承类
// 移动这个行为,属于鹦鹉
interface IMove extends Parrot{
name:string;
movefn(){};
}
var o :IMove = {
name:string
movefn:function
}
//泛型在函数中的具体运用
//函数声明
function sum<T>(n1:T,n2:T):T[] {
return [n1,n2]
}
//函数表达式
let sum1 = function<U>(n1:U,n2:U):U[] {
return [n1,n2]
}
//ES6
let sum2 = <U>(n1:U,n2:U):U[] =>[n1,n2];
sum2<string>('1','2');
//泛型的约束
interface ILengthNum {
length:number;
}
function len<T extends ILengthNum>(str:T):number {
return str.length
};
len('123');
//泛型 接口 约束函数
interface IFn{
<T>(a:T,b:T):boolean
}
let isFlag:IFn = function(x,y){
return x==y
};
isFlag<number>(4,8)
//把泛型参数提前放在接口名上
interface IFn<T>{
(a:T,b:T):boolean
}
let isFlag:IFn<number> = function(x,y){
return x==y
};
isFlag<number>(4,8)
//另一种写法
let isFlag:IFn<number>;
isFlag= function(x,y){
return x==y
};