函数有单独的类型Function
语法:(形参:类型,形参:类型…)=>函数体
// 定义一个类型,约束好结构
type myFun = (m:number, n:number)=>number;
let fun02:myFun = function(a:number, b:number){
return a+b;
}
let fun03:myFun = (a:number, b:number) => a*b;
// 类型有约束的作用
let fun04:(m:number, n:number)=>number = function(a:number, b:number){
return a-b;
}
let fun05 = function(a:number, b:number){
return a+a+b+b;
}
console.log(fun02(1,2));
console.log(fun03(1,2));
console.log(fun04(1,2));
console.log(fun05(1,2));
// 定义一个类型,约束好结构
type myFun = (m:number, n:number)=>number;
function calc(m:number, n:number, fn:myFun){
return fn(m, n);
}
// 定义好了类型,你要使用时候按照这个类型约束去实现
let result1 = calc(10, 20, (a:number, b:number)=>a+b);
let result2 = calc(20, 30, function(a:number, b:number){
return a*b;
})
console.log(result1);
console.log(result2);
let user:{
name:string,
age:number,
fun:()=>void
}
user = {
name: 'zs',
age: 10,
fun() {
console.log(`${this.name}--${this.age}`);
},
}
user.fun();
函数的可空参数
const func01:(m:number, n:number)=>number = function(a, b){
return a + b;
}
// n?表示参数可空
const func02 = function(m:number, n?:number):number{
return m;
}
函数参数默认值
const fun01 = function(a:number = 1, b:number = 2){
// 这里可以类型推断返回值类型
return a + b;
}
console.log(fun01());
console.log(fun01(100,200));
函数剩余参数
function fun01(a:number, b:number, ...args:number[]){
let result:number = a + b;
if(args.length>0){
for(var i=0;i<args.length;i++){
result+=args[i];
}
}
return result;
}
console.log(fun01(1,2));
console.log(fun01(100,200,300,400));
函数重载
// 定义函数类型,约束
function add(a:number, b:number):number;
// 重载了,参数类型,参数位置,参数个数不同即重载
function add(a:string, b:string):string;
function add(a:number,b:string):string;
function add(a:string,b:number):string;
// 真正的实现了
function add(a:any, b:any):any{
return a+b;
}
// 调用,调用就会去匹配类型看是否符合约束。
console.log(add(1, 2));
console.log(add(1,'hello'));
// console.log(add(1, 2, 3)); 报错,没有符合的约束
传统方法中,JavaScript通过构造函数实现类的概念,通过原型链实现继承。而在ES6中,我们终于迎来了class。
TypeScript除了实现了所有ES6中类的功能以外,还添加了一些新的用法。
// 定义一个类
class Person{
name: string;
age: number;
// 类的构造方法
constructor(name:string, age:number=10){
this.name = name;
this.age = age;
}
say(){
console.log(this.name+"说话");
}
}
const p1 = new Person('张三');
const p2 = new Person('李四', 40);
console.log(`${p1.name}--${p1.age}`);
console.log(`${p2.name}--${p2.age}`);
类的用法
继承可以理解为扩展,如果一个类的功能不全,我可以继承这个类,扩展其功能。
如果有多个类,有共有的方法,可以提取出来形成一个父类。保证代码的可重用性,可复用性。
// 定义一个类
class Person{
name: string;
age: number;
// 类的构造方法
constructor(name:string, age:number=10){
this.name = name;
this.age = age;
}
say(){
console.log(this.name+"说话");
}
}
class Student extends Person{
school:string;
constructor(name:string, age:number, school:string){
// 调用父类的构造方法
super(name, age);
this.school = school;
}
study(){
console.log(`学生${this.name}学习`);
}
}
class Teacher extends Student{
price:number;
constructor(name:string, age:number, school:string, price:number){
super(name, age, school);
this.price = price;
}
bk(){
// 调用父类的方法
super.study();
console.log(`老师${this.name}备课`);
}
}
const t = new Teacher('赵钱', 35, '玉清中学', 8000);
t.bk();
访问修饰符
TypeScript可以使用三种访问修饰符,分别是public、private、和protected
参数属性
如下例封装案例,一个类有很多方法,有用的方法暴露出去,其他服务的方法加上private
class Person{
private name:string;
private _age:number;
constructor(name:string,age:number){
this.name = name;
this._age = age;
}
set Age(age:number){
this._age = age;
}
get Age(){
return this._age;
}
// 对外我只暴露eat()这个方法即可。
public eat(){
this.qc();
this.zf();
this.kc();
}
// 这些方法是一些服务方法为eat()服务的
private qc(){
console.log('切菜');
}
private zf(){
console.log('煮饭');
}
private kc(){
console.log('开搓')
}
}
const p = new Person('张三', 30);
p.eat();
console.log(p.Age);
p.Age = 100;
console.log(p.Age);
static
使用static修饰符修饰的方法称为静态方法,它们不需要实例化,而是直接通过类来调用实例属性。
静态成员存放在静态代码块中,而实例成员存放在堆内存中。
多个对象共用的就用static来修饰。
class Student{
static school:string = '玉清中学';
name:string;
age:number;
constructor(name:string, age:number){
this.name = name;
this.age = age;
};
sayHi(){
console.log(`hello,大家好,我是${Student.school}的${this.name},我今年${this.age}岁了`);
}
}
const s1 = new Student('张三', 20);
const s2 = new Student('李四', 30);
s1.sayHi();
s2.sayHi();