03_基础静态类型与对象静态类型
a 对象类型
const car:{name:string,price:number}={name:'奔驰',price:12222}
b 数组类型
const cars :string[]=['奔驰‘,'宝马‘]
c 类类型
const Car{}
const car:Car=new Car()
d函数类型
const car :() =>string =()=>{return '奔驰'}
05 函数参数与返回值
函数参数为对象(解构)时
function add({ one, two }: { one: number, two: number }): number {
return one + two;
}
const three = add({ one: 1, two: 2 });
只有一个对象时,更易写错
unction getNumber({ one }: { one: number }): number {
return one;
}
const one = getNumber({ one: 1 });
06_数组对象类型的定义
a一般数组类型的定义
const arr: (number | string)[] = [1, "string", 2];
b数组对象类型的定义
方法一:
const xiaoJieJies: { name: string, age: Number }[] = [
{ name: "刘英", age: 18 },
{ name: "谢大脚", age: 28 },
];
方法二:
采用类型别名
type Lady = { name: string, age: Number };
const xiaoJieJies: Lady[] = [
{ name: "刘英", age: 18 },
{ name: "谢大脚", age: 28 },
];
方法三 使用类 可以使用类限制数组
class Madam {
name: string;
age: number;
}
const xiaoJieJies: Madam[] = [
{ name: "刘英", age: 18 },
{ name: "谢大脚", age: 28 },
];
07_元组
"dajiao", "teacher", 28;
"liuying", "teacher", 18;
"cuihua", "teacher", 25;
类似与csv类型,用逗号隔开,需要使用到元组
const xiaojiejies: [string, string, number][] = [
["dajiao", "teacher", 28],
["liuying", "teacher", 18],
["cuihua", "teacher", 25],
];
08_interface接口
提高代码重用性
a ?非必选
元组与接口区别?元组可以type girl=string 但是接口表示对象
b 允许加入任意值
[propname:string]:any propname表示属性名 string表示属性名字为字符串类型 any表示属性值为任意类型
c 接口定义方法
interface Girl {
name: string;
age: number;
bust: number;
waistline?: number;
[propname:string]:any;
say():string;
}
有了接口后,我们的程序也要作一些修改,需要写成下面的样子。这样就更像是面向对象编程了。
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,
waistline:21, //可选
sex:"女", //允许添加任意类型
say(){
return 'hello'; //接口添加方法 对象必须添加且必须有返回类型 否则会报错
}
};
screenResume(girl);
getResume(girl);
d 接口与类的约束
类要实现接口,必须添加接口定义的方法和属性
class XiaoJieJie implements Girl {}
这时候类会直接报错,所以我们需要把这个类写的完全点。
class XiaoJieJie implements Girl {
name = "刘英";
age = 18;
bust = 90;
say() {
return "欢迎光临 ,红浪漫洗浴!!";
}
}
e 接口间继承
接口也可以用于继承的,比如你新写一个Teacher
接口,继承于Person
接口。
interface Teacher extends Girl {
teach(): string;
}
比如这时候老板说了,只看 Teacher 级别的简历,那我们需要修改getResume()
方法。
const getResume = (girl: Teacher) => {
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);
};
修改后,你就会发现下面我们调用getResume()
方法的地方报错了,因为这时候传的值必须有Teach
方法,
getResume(girl);
修改girle
对象,增加teach()
方法,这时候就不会报错了。
const girl = {
name: "大脚",
age: 18,
bust: 94,
waistline: 21,
sex: "女",
say() {
return "欢迎光临 ,红浪漫洗浴!!";
},
teach() {
return "我是一个老师";
},
};
接口只是在 TypeScript 里帮我们作语法校验的工具,编译成正式的js
代码,就不会有任何用处了。
10_类概念与使用
a 类的继承
b 类的重写
c super关键字使用
super 表示的是调用父类的方法
class XiaoJieJie extends Lady {
sayLove() {
return "I love you!";
}
sayHello() {
return super.sayHello() + "。你好!";
}
}
d 类的访问类型
public 公共
private 内部调用
protected 类内部与子类调用
e 构造函数
class Person{}
class Teacher extends Person{
constructor(public age:number){
super()
}
}
const teacher = new Teacher(18)
console.log(teacher.age)
子类必须使用super() 调用父类的构造函数 。
f setter与getter
当想封装某属性 ,使用private ,不允许外界调用时
外界只能通过get和set访问与改变
class Xiaojiejie {
constructor(private _age:number){}
get age(){
return this._age-10
}
set age(age:number){
this._age=age
}
}
const dajiao = new Xiaojiejie(28)
dajiao.age=25
console.log(dajiao.age)
g 静态属性类
用static
声明的属性和方法,不需要进行声明对象,就可以直接使用
class Girl {
static sayLove() {
return "I Love you";
}
}
console.log(Girl.sayLove());
h 只读属性 readonly
readonly 只读不允许修改
class Person {
public readonly _name :string;
constructor(name:string ){
this._name = name;
}
}
const person = new Person('jspang')
person._name= '谢广坤'
console.log(person._name)
i 抽象类
18_联合类型与类型保护
a 联合类型,可以认为一个变量可能有两种或两种以上的类型
声明两个接口Waiter
(服务员)接口和Teacher
(技师)接口,然后在写一个judgeWho
(判断是谁)的方法,里边传入一个animal
(任意值),这时候可以能是Waiter
,也可能是Teacher
。所以我们使用了联合类型,关键符号是|
(竖线)。
interface Waiter {
anjiao: boolean;
say: () => {};
}
interface Teacher {
anjiao: boolean;
skill: () => {};
}
function judgeWho(animal: Waiter | Teacher) {}
通过这个简单的例子,你应该知道什么是联合类型了。
function judgeWho(animal: Waiter | Teacher) {
animal.say();
}
但这时候问题来了,如果我直接写一个这样的方法,就会报错,因为judgeWho
不能准确的判断联合类型具体的实例是什么。
b 类型保护-类型断言 as
通过断言animal as Teacher
,然后直接调用skill
方法,程序就不再报错了。同样如果不会按脚,说明就是不同的服务员,这时候调用say()
方法,就不会报错了
interface Waiter {
anjiao: boolean;
say: () => {};
}
interface Teacher {
anjiao: boolean;
skill: () => {};
}
function judgeWho(animal: Waiter | Teacher) {
if (animal.anjiao) {
(animal as Teacher).skill();
}else{
(animal as Waiter).say();
}
}
b 类型保护-in
用if
来判断animal
里有没有skill()
方法
function judgeWhoTwo(animal: Waiter | Teacher) {
if ("skill" in animal) {
animal.skill();
} else {
animal.say();
}
}
c 类型保护-typeof
写一个新的add
方法,方法接收两个参数,这两个参数可以是数字number
也可以是字符串string
,如果我们不做任何的类型保护,只是相加,这时候就会报错。代码如下:
function add(first: string | number, second: string | number) {
return first + second;
}
直接使用typeof
来进行解决。
function add(first: string | number, second: string | number) {
if (typeof first === "string" || typeof second === "string") {
return `${first}${second}`;
}
return first + second;
}
d-类型保护instanceof
比如现在要作类型保护的是一个对象,这时候就可以使用instanceof
语法来作。现在先写一个NumberObj
的类,代码如下:
class NumberObj {
count: number;
}
然后我们再写一个addObj
的方法,这时候传递过来的参数,可以是任意的object
,也可以是NumberObj
的实例,然后我们返回相加值,当然不进行类型保护,这段代码一定是错误的。
function addObj(first: object | NumberObj, second: object | NumberObj) {
return first.count + second.count;
}
报错不要紧,直接使用instanceof
语法进行判断一下,就可以解决问题。
function addObj(first: object | NumberObj, second: object | NumberObj) {
if (first instanceof NumberObj && second instanceof NumberObj) {
return first.count + second.count;
}
return 0;
}
另外要说的是,instanceof 只能用在类上。
19_Enum枚举类型
enum Status {
MASSAGE,
SPA,
DABAOJIAN,
}
function getServe(status: any) {
if (status === Status.MASSAGE) {
return "massage";
} else if (status === Status.SPA) {
return "spa";
} else if (status === Status.DABAOJIAN) {
return "dabaojian";
}
}
const result = getServe(Status.SPA);
console.log(`我要去${result}`);
a 枚举类型是有对应的数字值的,默认是从 0 开始的
你调用时传一个1
,也会输出我要去spa
。
const result = getServe(1);
不想默认从 0 开始,而是想从 1 开始。可以这样写。
enum Status {
MASSAGE = 1,
SPA,
DABAOJIAN,
}
b 枚举可以通过下标反查
console.log(Status.MASSAGE, Status[1]);