定义
定义一个布尔值
let isDone:boolean = false
定义一个数值类型
let num:number = 1;
定义一个字符串
let myName:string = "Tom"
let str:string=`Hello,my name is ${myName}`
定义一个空值:void
function alterName(): void {
alert("hello")
}
任意值any-允许赋值为任意类型
let myfavourite:any = 'seven'
myfavourite = 7;
console.log(myfavourite)
// 方法也是可以的
let anyThing:any = 'Tom';
anyThing.setName('Jerry');
anyThing.setName('Jerry').sayHello();
类型推论
let str;
str = 7;
str = 'seven';
str = false;
console.log(str)
联合类型
let myfavouriteName: string | number;
myfavouriteName = 'seven';
myfavouriteName = 7;
接口
在TS中,我们使用interface来定义一个接口类型的对象。
接口是对行为的抽象,而具体如何行动需要类去实现。
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 25
}
任意属性
interface Person {
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
name: 'Tom',
age: 25
}
只读属性
readonly
数组
存放多个元素的集合
let temp: number[] = [1,2,3,4,,5,6]
// temp.push('7') 不能有其他类型
console.log(temp)
let temp1:any[] = [1,2,3,6,4,5,'7',true]
console.log(temp1)
函数 函数声明,函数表达式
// 函数声明
function sum(x:number,y:number):number{
return x+y
}
sum(1,2)
// 函数表达式
let mySum = function sum(x:number,y:number):number{
return x+y
}
// 如果手动指定类型
let mySum2: (x: number,y:number) =>number =function sum(x:number,y:number):number{
return x+y
}
通过接口定义函数的形状
interface SearchFunc{
(source:string,subString:string):boolean;
}
剩余参数...rest,重载
//
function push(array: any[],...items:any[]) {
items.forEach(function(item){
array.push(item);
})
}
let a = [];
push(a,1,2,3,'4','5',true);
// 重载
function reverse(x:number|string):number|string|void{
if(typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('')
}
}
reverse(1)
reverse('1')
类型断言
将一个联合类型断言为一个指定类型,使用as关键字
interface Cat{
name: string;
run(): void;
}
interface Fish{
name: string;
swim(): void;
}
function isFish(animal: Cat|Fish) {
if(typeof (animal as Fish).swim === 'function') {
return true;
}
return false
}
将一个父类断言为更加具体的子类
class ApiError extends Error{
code: number = 0;
}
class HttpError extends Error {
statusCode: number = 200;
}
function isApiError(error: Error) {
if(typeof (error as ApiError).code === 'number') {
return true;
}
return false;
}
任何类型都可以断言为any
// 将一个变量断言为any是解决ts问题的最后一个手段
(window as any).foo = 1;
console.log((window as any).foo)
// 将any断言为更加具体的内容
function getCatchData(key: string): any{
return (window as any).catch[key];
}
interface Cat {
name: string;
run(): void;
}
代码由不确定性向确定性的方向迁移
const tom = getCatchData('tom') as Cat;
tom.run()
类型断言的限制
并不是任何一个类型都可以断言为任何一个类型,两者之间有共同的属性或者方法,就可以互相断言
interface Animal {
name: string;
}
interface Cat {
name: string;
run():void;
}
function testAnimal(animal:Animal){
return (animal as Cat);
}
function testCat(cat:Cat) {
return (cat as Animal)
}
双重断言--除非迫不得已,千万不能用
interface Cat{
run(): void;
}
interface Fish{
swim(): void;
}
function testCat1(cat:Cat){
return (cat as any as Fish);
}
类型断言和类型转换
类型断言不会真正的影响变量类型
类型断言vs类型声明
a断言为b时,a和b有重叠的部分即可 a声明为b时,a必须具备b所有的属性和方法
const tom2 = getCatchData('tom') as Cat;
// 类型声明
const tom1:Cat = getCatchData('tom');
tom.run()
断言和泛型
function getCatchData1<T>(key:string): T {
return (window as any).cache[key];
}
interface Cat {
name: string;
run():void;
}
const tom3 = getCatchData1<Cat>('tom')
tom.run()
使用type关键字定义类型别名和字符串字面量类型
type Name = string;
type NameResolver = () => string;
type NameOrResolver= Name | NameResolver;
function getName(n:NameOrResolver):Name{
if(typeof n === 'string') {
return n;
} else {
return n();
}
}
元组
数组合并了相同类型的对象,而元组合并了不同类型的对象
let tom:[string,number] = ['tom',25]
console.log(tom[0],tom[1])
枚举--取值被限定在一定范围内的场景
enum Days {Sun,Mon,Tus};
console.log(Days["Sun"] === 0)
console.log(Days[0] === "Sun");
类 构造函数 属性 方法
定义了一件事物的抽象特点,包含它的属性和方法,面向对象三大特点 :封装继承多态 使用class定义类,使用constructor定义构造函数
class Animal {
public _name;
constructor(name:string) {
this._name = name;
}
sayHi() {
return `My name is ${this._name}`
}
}
let a = new Animal('Jack');
console.log(a.sayHi());
类 存取器get set
class Animal1{
constructor(name){
this.name = name;
}
get name() {
return 'Jack'
}
set name(value) {
console.log('setter:' + value)
}
}
let b = new Animal1('Kitty')
b.name = 'Tom'
console.log(b.name)
类,静态方法 使用static修饰
// public 全局的,公共的
class Animal3{
public _name;
constructor(name:string) {
this._name = name;
}
sayHi() {
return `My name is ${this._name}`
}
static sayHello(){
return "hello"
}
}
let a2 = new Animal3('Jack');
// 非静态方法,通过类的实例来调用
console.log(a2.sayHi())
// 静态方法使用static类修饰,使用的时候直接通过类来调用
console.log(Animal3.sayHello())
// private 私有的 只能在类的内部使用
// protected 受保护的,允许子类访问
类 参数属性和只读关键字
class Animal4{
readonly name;
public constructor(public name:string) {
this.name = name
}
}
抽象类
abstract 用于定义抽象类和其中的抽象方法
抽象类不允许被实例化
抽象类本身不能去实例化,需要通过子类去继承,然后由子类实现抽象类的方法
abstract class Animal5{
public name;
public constructor(name:string) {
this.name = name;
}
public abstract sayHi():void
}
// let a = new Animal5('Jack')
class Cat extends Animal5{
public sayHi() {
console.log(`Memo,My name is ${this.name}`)
}
}
let cat = new Cat('tom')
cat.sayHi()
类与接口
interface Alarm{
alert():void;
}
class Door{}
class SecurityDoor extends Door implements Alarm{
alert() {
console.log('防盗门')
}
}
class Car implements Alarm{
alert() {
console.log('Car alert')
}
}
一个类可以实现多个接口
常见面向对象语言中,接口是不能继承类的,但是在Ts中是可以实现的
// 通过泛型来指定类型
function createArray<T>(length:number,value:T):Array<T>{
let result:T[] = [];
for(let i =0;i<length;i++) {
result[i] = value;
}
return result;
}
// 可以不指定类型,通过类型推断类自动推断类型
createArray<string>(3,'x')
泛型 多个类型参数
function swap<T,U>(tuple:[T,U]):[U,T]{
return [tuple[1],tuple[0]];
}
console.log(swap([7,'seven']))
泛型约束
interface Lengthwise{
length: number;
}
泛型接口
interface CreateArrayFunc<T>{
(length:number,value:T):Array<T>;
}
let createArray1:CreateArrayFunc<string>;
createArray1 = function<T>(length:number,value:T):Array<T>{
let result:T[] = [];
for(let i = 0;i<length;i++){
result[i] = value;
}
return result;
}
createArray1(3,'x')
声明合并,同名函数
如果定义了两个相同名字的函数,接口或类,那么它们会合并成一个类型
interface ALarm{
price:number;
}
interface Alarm{
weight: number;
}