全局安装ts:npm install -g typescript
检验版本 tsc -v
ts有哪些数据类型:
- string
- number
- boolean
- undefined
- null
- enum
- sysbol
- void
- any
- type Name = boolean | number | "男"
ts具有类型校验功能,写错会报错但不影响编译成js及运行。
let a : string = "2"
a = 1 报错
a = null 不会报错
因为undefined 和null属于string,number ,boolean 的子类型,
初始化未赋值的变量默认any类型
let a; // 默认加上:any
初始化赋值的变量将按类型推断
let a = 1; // 默认加上:number
联合类型,例:
let a:nummber | string = 1; // number 和 string 类型都可
接口,习惯以I为首字母并大写
intefacr Istate = {
name : string ,
readonly isMarry : boolean // readonly 只读
age? : number, // ? 可选属性
[propName:string] : any // 属性数量不限
}
let a : Istate = {
name : "张一山",
age:18,
sex:"男"
}
funtion getUserInfo(user1:Istate){
return "姓名:" + user1.name + "-年龄:" + user1.age
}
// 函数类型接口
// 接口能够描述 JavaScript 中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述
// 函数类型。
// 为了使用接口表示函数类型,我们需要给接口定义一个调用签名。它就像是一个只有参数列表和返回值类型的函// // 数定义。参数列表里的每个参数都需要名字和类型。
interface SearchFunc {
(source: string, subString: string): boolean
}
// 这样定义后,我们可以像使用其它接口一样使用这个函数类型的接口。 下例展示了如何创建一个函数类型的变// // 量,并将一个同类型的函数赋值给这个变量。
const mySearch: SearchFunc = function (source: string, sub: string): boolean {
return source.search(sub) > -1
}
console.log(mySearch('abcd', 'bc'))
/*
类类型: 类实现接口
1. 一个类可以实现多个接口
2. 一个接口可以继承多个接口
*/
interface Alarm {
alert(): any;
}
interface Light {
lightOn(): void;
lightOff(): void;
}
class Car2 implements Alarm, Light {
alert() {
console.log('Car alert');
}
lightOn() {
console.log('Car light on');
}
lightOff() {
console.log('Car light off');
}
}
// 接口继承接口
interface LightableAlarm extends Alarm, Light {
}
数组
// 类型 + 中括号
let arr1 : string [] = ["1","2","3"];
let arr2 : any [] = [1,"2",true];
//泛型写法
let arr3 : Array<string> = ["1","2","3"];
let arr4 : Array<any> = [1,"2",true];
//接口写法
interface Istate{
name : string,
age : number
}
interface Iarr{
[index: number] : Istate
}
let arr5 : Iarr = [{name:"张一山",age:12}];
let arr6 : Array<Istate> = [{name:"张一山",age:12}];
函数
function setState(name:string, age:number, sex?:string): number{
return age
}
// 联合函数重载
function getValue(value : string) : string;
function getValue(value : number) : number;
function getValue(value : string | number){
return value;
}
// 表达式类型函数验证方式 name参数默认值"张一山"
let func : (name:string , age : number) => number = function(name:string = "张一山", age : number) : number{
return age
}
// 类型断言(number没有.length方法,需要转换成string,断言类型仅支持联合函数中的类型)
function getLength(val : number | string){
return (<string>val).length;
或者(react的jsx语法的ts版仅支持下面这个)
return (val as string).length;
}
枚举
enum names {
"wang",
"li",
"zhang",
"liu",
}
names[0] === "wang" // true
names["wang"] === 0 // true
类*****(很重要)
类的修饰符
- public // 默认 公有
- private // 私有 类内部可访问
- protected // 半私有 类内部和子类可以访问
// 例子1
class Father {
name : "父亲"
say(){
console.log("我是" + super.name )
}
}
// 继承, 用super调用父类方法,属性(包括私有属性及方法)
// java里子类不可以访问父类的私有属性或方法,
class Son extends Father {
// 子类方法会覆盖父类同名方法
say(){
console.log("我是" + super.name + "的儿子")
}
// 静态方法不需要new,可以直接Son.go()
static go(){
conosle.log("让我们荡起双桨,小船儿推开波浪,海面倒映着美丽的白塔,四周环绕着绿树红墙。")
}
}
let son1 = new Son();
son1.say(); // 我是父亲的儿子
Son.go() // 让我们荡起双桨,小船儿推开波浪,海面倒映着美丽的白塔,四周环绕着绿树红墙。
// 例子2
class User {
fullName: string
firstName: string
lastName: string
constructor (firstName: string, lastName: string) {
this.firstName = firstName
this.lastName = lastName
this.fullName = firstName + ' ' + lastName
}
}
interface Person {
firstName: string
lastName: string
}
function greeter (person: Person) {
return 'Hello, ' + person.firstName + ' ' + person.lastName
}
let user = new User('Yee', 'Huang')
console.log(greeter(user))
类继承*****
/*
类的继承
*/
class Animal {
run (distance: number) {
console.log(`Animal run ${distance}m`)
}
}
class Dog extends Animal {
cry () {
console.log('wang! wang!')
}
}
const dog = new Dog()
dog.cry()
dog.run(100) // 可以调用从父中继承得到的方法
这个例子展示了最基本的继承:类从基类中继承了属性和方法。 这里,Dog 是一个 派生类,它派生自 Animal 基类,通过 extends 关键字。 派生类通常被称作子类,基类通常被称作超类。
因为 Dog 继承了 Animal 的功能,因此我们可以创建一个 Dog 的实例,它能够 cry() 和 run()。
下面我们来看个更加复杂的例子。
class Animal {
name: string
constructor (name: string) {
this.name = name
}
run (distance: number=0) {
console.log(`${this.name} run ${distance}m`)
}
}
class Snake extends Animal {
constructor (name: string) {
// 调用父类型构造方法
super(name)
}
// 重写父类型的方法
run (distance: number=5) {
console.log('sliding...')
super.run(distance)
}
}
class Horse extends Animal {
constructor (name: string) {
// 调用父类型构造方法
super(name)
}
// 重写父类型的方法
run (distance: number=50) {
console.log('dashing...')
// 调用父类型的一般方法
super.run(distance)
}
xxx () {
console.log('xxx()')
}
}
const snake = new Snake('sn')
snake.run()
const horse = new Horse('ho')
horse.run()
// 父类型引用指向子类型的实例 ==> 多态
const tom: Animal = new Horse('ho22')
tom.run()
/* 如果子类型没有扩展的方法, 可以让子类型引用指向父类型的实例 */
const tom3: Snake = new Animal('tom3')
tom3.run()
/* 如果子类型有扩展的方法, 不能让子类型引用指向父类型的实例 */
// const tom2: Horse = new Animal('tom2')
// tom2.run()
抽象类
抽象类做为其它派生类的基类使用。 它们不能被实例化。不同于接口,抽象类可以包含成员的实现细节。 abstract 关键字是用于定义抽象类和在抽象类内部定义抽象方法。
/*
抽象类
不能创建实例对象, 只有实现类才能创建实例
可以包含未实现的抽象方法
*/
abstract class Animal {
abstract cry ()
run () {
console.log('run()')
}
}
class Dog extends Animal {
cry () {
console.log(' Dog cry()')
}
}
const dog = new Dog()
dog.cry()
dog.run()
泛型
function creatArr<T>(val:T):Array<T>{
// 一顿操作
let a : Array<T> = []
return a;
}
let strNum : Array<number> = creatArr(1) // true
let strNum2 : Array<number> = creatArr("1") // false