开发环境搭建
- node安装
- 全局安装TypeScript
npm install typescript -g
- 新建一个文件
Demo1.ts
,写入如下代码
function jspang() {
let web: string = "Hello World";
console.log(web);
}
jspang();
// 基础运行
-- tsc Demo1.ts // 此时会生成一个同名js文件
-- node Demo1.js
// 使用ts-node插件
-- ts-node Demo1.ts
- ts-node 的安装和使用
npm install -g ts-node
安装完成后,就可以在命令中直接输入如下命令,来查看结果了。ts-node Demo1.ts
一、TypeScript的静态类型
基础静态类型
string
,number
,boolean
,null
,undefined
,void
,symbol
对象类型
object
,array
,class
,function
// 对象类型
// 1. object
const xie:{
name:string,
age:number
} = {
name:'xiedajiao',
age:18
}
console.log(xie);
// 2. array
const foods:string [] = ['apple','milk','orange']
console.log(foods);
// 3. class
class Person{}
let zhang:Person = new Person()
console.log(zhang);
// 4.function
const func:()=>string =()=>{ return 'xie' } // it means that this function must return a string type data,or else it will occur an error
console.log(func());
自定义静态类型 interface
// 自定义静态类型
interface person{
name:string,
age:number
}
let xie:person = {
name:'xieyc',
age:18
}
console.log(xie)
输出:
二、annotation类型注解/inferance类型推断
ts自身具有类型推断功能,当一个数据可以被ts推断出来数据类型时,则可以不用类型注解,当无法被推断出来时,则需要使用类型注解。ts同样可以推断出对象中的属性类型。
// annotation类型注解/inferance类型推断
// 1. automatically inference
let num = 123;
// 2. have to annotate
// as example below,ts inferance a & b as 'any' type,it means you have to annotate type for a & b
function add1(a,b){
return a + b
}
add1(1,2)
// change it like below
function add2(a: number,b: number){
return a + b
}
add2(1 , 2)
三、函数参数定义和返回类型的注解
设定函数返回类型
// set function return type
// 1. have return value
function add2(a: number,b: number):number{
return a + b
}
let count = add2(1 , 2)
// 2. if there's no return,then set return type as void instead
function fun():void{
console.log("I don't return anything")
}
// 3. 如果函数死循环或是抛出异常,则可以使用never类型
function errFunc():never{
throw new Error();
}
// 4.函数对象(解构)时
function add({ one, two }: { one: number, two: number }): number {
return one + two;
}
const three = add({ one: 1, two: 2 });
四、TS中数组类型的定义
// 1. 默认情况,能自动识别
const numberArr = [1, 2, 3];
// 2. 数据都是用一类型
const numberArr: number[] = [1, 2, 3];
const stringArr: string[] = ["a", "b", "c"];
const undefinedArr: undefined[] = [undefined, undefined];
// 3. 数组中有多种类型
const arr: (number | string)[] = [1, "string", 2];
// 4. 数组中对象的定义
const xiaoJieJies: { name: string, age: Number }[] = [
{ name: "刘英", age: 18 },
{ name: "谢大脚", age: 28 },
];
// 这种写法比较麻烦,于是TS中为我们准备了一个概念,叫做类型别名(type alias)。
// 比如刚才的代码,就可以定义一个类型别名,定义别名的时候要以type关键字开始。现在定义一个Lady的别名。
type Lady = { name: string, age: Number };
const xiaoJieJies: Lady[] = [
{ name: "刘英", age: 18 },
{ name: "谢大脚", age: 28 },
];
//这样定义是完全起作用的,比如我们下面在对象里再加入一个属性,这时候编译器就会直接给我们报错了。
// 5. 用类进行定义
class Madam {
name: string;
age: number;
}
const xiaoJieJies: Madam[] = [
{ name: "刘英", age: 18 },
{ name: "谢大脚", age: 28 },
];
五、TS中元组的使用和类型约束
六、TS中的interface接口
interface接口
// 定义接口
interface Girl {
name: string;
age: number;
bust: number;
}
const screenResume = (girl: Girl) => {
girl.age < 24 && girl.bust >= 90 && console.log(girl.name + "进入面试");
girl.age > 24 || (girl.bust < 90 && console.log(girl.name + "你被淘汰"));
};
const getResume = (girl: Girl) => {
console.log(girl.name + "年龄是:" + girl.age);
console.log(girl.name + "胸围是:" + girl.bust);
};
const girl = {
name: "大脚",
age: 18,
bust: 94,
};
screenResume(girl);
getResume(girl);
接口和类型别名的区别
类型别名可以直接给类型,比如
string
,而接口必须代表对象。
//比如我们的类型别名可以写出下面的代码:
type Girl1 = stirng;
//但是接口就不能这样写,它必须代表的是一个对象,也就是说,你初始化girl的时候,必须写出下面的形式.
const girl = {
name: "大脚",
age: 18,
bust: 94,
};
接口非必选值得定义
interface Girl {
name: string;
age: number;
bust: number;
waistline?: number;
}
//这时候在定义girl对象的时候,就可以写saistline(腰围),也可以不写了。
const getResume = (girl: Girl) => {
console.log(girl.name + "年龄是:" + girl.age);
console.log(girl.name + "胸围是:" + girl.bust);
girl.waistline && console.log(girl.name + "腰围是:" + girl.waistline);
};
允许加入任意值
简历一般是有自由发挥的空间的,所以这时候需要一些任意值,就是自己愿意写什么就写什么。这时候interface
接口也是支持的。
//这个的意思是,属性的名字是字符串类型,属性的值可以是任何类型。
interface Girl {
name: string;
age: number;
bust: number;
waistline?: number;
[propname: string]: any;
}
//这时候我们在对象里给一个性别,代码如下:
const girl = {
name: "大脚",
age: 18,
bust: 94,
waistline: 21,
sex: "女",
};
//再修改一下代码,这首就没有错误了。
const getResume = (girl: Girl) => {
console.log(girl.name + "年龄是:" + girl.age);
console.log(girl.name + "胸围是:" + girl.bust);
girl.waistline && console.log(girl.name + "腰围是:" + girl.waistline);
girl.sex && console.log(girl.name + "性别是:" + girl.sex);
};
//这时候我们的程序是不报错的,但是如果我们去掉刚才的设置,就会报错。
接口里的方法
接口里不仅可以存属性,还可以存方法,比如这时候有个say()
方法,返回值是string
类型。这时候你就不要再想成简历了,你需要更面向对象化的编程,想象成一个人。
interface Girl {
name: string;
age: number;
bust: number;
waistline?: number;// 定义这个代表这个属性可有可无
[propname: string]: any; //定义了这个就基本不会报错了
say(): string;
}
//加上这个say()方法后,程序马上就会报错,因为我们对象里没有 say 方法。那我们就要给对象一个 say 方法
const girl = {
name: "大脚",
age: 18,
bust: 94,
waistline: 21,
sex: "女",
say() {
return "欢迎光临 ,红浪漫洗浴!!";f
},
};
// 总结一下:就是接口中定义的数据(除?和[propname: string]: any;外)的,在使用是都必须赋值,如果有不确定值,或是可有可无的值时,就使用?和[propname: string]: any;
接口和类的约束
我们都知道 JavaScript 从ES6
里是有类这个概念的,类可以和接口很好的结合,我们先来看一个例子。下面的
class XiaoJieJie implements Girl {}
//这时候类会直接报错,所以我们需要把这个类写的完全点。
class XiaoJieJie implements Girl {
name = "刘英";
age = 18;
bust = 90;
say() {
return "欢迎光临 ,红浪漫洗浴!!";
}
}
接口间的继承
七、类的概念和使用
一、继承 extends
- 子类继承父类则继承父类所有属性和方法,祖先类的属性和方法也会继承。
重写
:直接复写父类中的方法。- 在重写时想用父类的属性/方法,可以使用
super.funcnName()
调用父类属性/方法。
二、类的访问类型
private
、protect
、public
- 类中属性未定义访问类型,默认为
public
public
: 公共的,在类的外部和内部都可以使用private
: 私有的,只能在类的内部使用,不能在子类中使用,无法被继承。protect
: 受保护的,类似于private,在类的内部使用,区别在于,它可以被继承,在继承它的子类中使用。
三、构造函数
在new一个对象的时候可以直接执行,子类继承父类时,要实现构造函数,必须实现父类构造函数方法。
四、get和set方法
属性使用private修饰,如果需要暴露给子类,那么就需要使用get、set方法。
五、静态类型 static
可以不用实例化一个对象,直接通过类就可以访问其属性/方法。
Person.name
六、抽象类和只读属性 readonly
// 抽象类
abstract class Girl{
abstract skill()
...
}
// 只读属性
public readonly name : string
主要应用场景:每一个继承的子类都要实现不同业务逻辑的方法。
- 所有继承于抽象类的子类都要实现其抽象方法。