函数

函数类型签名

  • 描述了函数入参类型与函数返回值类型
  • 要么直接在函数中进行参数和返回值的类型声明,要么使用类型别名将函数声明抽离出来
const foo = function (name: string): number {
return name.length
}

type FuncFoo = (name: string) => number

const foo: FuncFoo = (name) => {
return name.length
}

重载

  • 在某些逻辑较复杂的情况下,函数可能有多组入参类型和返回值类型:
function func(foo: number, bar?: boolean): string | number {
if (bar) {
return String(foo);
} else {
return foo * 599;
}
}

// 重载签名1
function func(foo: number, bar: true): string;
// 重载签名2
function func(foo: number, bar?: false): number;
// 实现签名,包含重载签名的所有可能情况。
function func(foo: number, bar?: boolean): string | number {
if (bar) {
return String(foo);
} else {
return foo * 599;
}
}

const res1 = func(599); // number
const res2 = func(599, true); // string
const res3 = func(599, false); // number
  • TypeScript 中的重载更像是伪重载:
    • 它只有一个具体实现,其重载体现在方法调用的签名上而非具体实现上
    • 而在如 C++ 等语言中,重载体现在多个名称一致但入参不同的函数实现上

class

  • 主要结构只有
    • 构造函数
    • 属性
    • 方法
    • 访问符(Accessor)

修饰符

  • public:访问性修饰符,此类成员在类、类的实例、子类中都能被访问。
  • private:访问性修饰符,此类成员仅能在类的内部被访问。
  • protected:访问性修饰符,此类成员仅能在类与子类中被访问
  • readonly:操作性修饰

关键字

static:静态成员

  • 类的内部静态成员无法通过 this 来访问,需要通过 Foo.staticHandler 这种形式进行访问
class Foo {
static staticHandler() { }

public instanceHandler() { }
}

override

  • 确保派生类尝试覆盖的方法一定在基类中存在定义,如下会报错,在基类中未声明print
class Base {
printWithLove() { }
}

class Derived extends Base {
override print() {
// ...
}
}

class的类型

  • 基类:class Base { }
  • 派生类:class Derived extends Base { }
  • 抽象类:abstract class Abstract{ } 描述了一个类中应当有哪些成员(属性、方法等)
abstract class AbsFoo {
abstract absProp: string;
abstract get absGetter(): string;
abstract absMethod(name: string): string
}
  • 实现一个抽象类implements
    • 必须完全实现这个抽象类的每一个抽象成员
class Foo implements AbsFoo {
get absGetter() {
return "linbudu"
}

absMethod(name: string) {
return name
}
}
const foo = new Foo()
foo.absProp = 'foo' // 报错

image-20231219114716447

  • interface 不仅可以声明函数结构,也可以声明类的结构:
    • interface 只是指定检查条件,如果不满足这些条件就会报错。它并不能代替 class 自身的类型声明。
interface A {
get(name:string): boolean;
}

class B implements A {
get(s) { // s 的类型是 any
return true;
}
}
  • 上面示例中,类B实现了接口A,但是后者并不能代替B的类型声明。因此,Bget()方法的参数s的类型是any,而不是stringB类依然需要声明参数s的类型。
class B implements A {
get(s:string) {
return true;
}
}

image-20231219115242014