前言

本文章主要记录平日coding过程中所遇到的未知知识,作为记录,便于后续查阅与学习!

typescript相关关键词

我比你ts编译器更懂:as

Typescript中,as关键词是用于类型断言的,这个类型断言是Typescript中的一个特性,允许开发者告诉编译器:“我知道这个变量的类型比你能推断出来的更具体”,类型断言更像是一种方式,用来“覆盖”Typescript中的类型推断,提供一个显示的类型。
使用as关键词一般来说有两个主要目的:

  1. 当比Typescript更了解某个值的具体类型时,可以使用类型断言来指定一个更具体的类型;
  2. 当需要将一个类型“断言”为另外一个兼容的类型时,用以调和不同的类型接口。
    🤔 比如 🈶 👇1⃣ 个例子:
    1
    2
    3
    const input: any = '这是一个字符串'
    // 下面使用as关键词进行类型断言
    const str: string = input as string
    🤩 这里告诉Typescript编译器,这个input是一个字符串,然后我们就可以来将其当成一个字符串来使用了!

类型断言虽然可以告知编译器某个变量的类型,但是它这里只是提供类型断言的目的,实际上是不会改变原始变量,而且,假如我们未能正确使用(将一个string来当作number来使用)的话,将会导致隐藏的bug在程序中!

有关函数的更多信息-类型定义

Typescript中,函数是任何应用的基本构建块,它也是一个值,既然作为一个值,那么它就可以作为参数、返回值等等方式来使用,如下所示:

1
2
3
4
5
6
7
function greeter(fn: (str: string) => void){
fn("hello world")
}
function printToColsole(s: string) {
console.info(s)
}
greeter(printToColsole)

🌠 这里我们定义了一个接收另外一个函数的greeter函数,然后将函数参数声明为:(str: string) => void,这代表printToColsole函数的参数是一个“接收一个字符串,没有返回值的函数”
👉 当然,我们还可以将上述的fn定义到一类型中,如下所示:

1
2
3
4
type GreetFunction = (str: string) => void
function greeter(fn: GreetFunction){
fn("hello world")
}

带有属性的函数调用

在js中,函数除了可调用之外,还可以拥有属性,但是像上面的函数类型声明语法是不允许我们声明属性的,
👉Typescript中可以通过以下的方式来定义一个具有属性的可调用类型

1
2
3
4
5
6
7
8
9
10
11
12
13
type DescribableFunction = {
description: string;
(someArg: number): boolean;
}
function doSomeThing(fn: DescribableFunction) {
console.info(fn.description + ' returned ' + fn(6))
}
function myFunc(someArg: number): boolean{
return someArg > 3
}
// 给调用赋值属性
myFunc.description = 'default description'
doSomeThing(myFunc)

🌟 上述这里我们通过将常规函数类型的声明中的=>替换为:,代表这个DescribableFunction是一个具有属性的可调用函数类型!

构造函数对象的定义-new

在js中可通过new关键词来对一个函数进行构造调用,那么 🤔 思考这样子的一个问题,如果将上述的关于“具有属性的可调用函数”类型,再加上这个new关键词,是否可以用来定义一个针对某个class的类型声明呢?
答案是是可以的,如下代码所示:

1
2
3
4
5
6
type SomeConstructor = {
new (s: string): SomeObject
}
function fn(ctor: SomeConstructor) {
return new ctor('hello')
}

🌟 这里我们定义了一个构造函数类型SomeConstructor,通过在常规的函数前面加上一个new关键词,代表这个函数是可以被通过new关键词进行构造调用的,因此在调用的时候,可通过new ctor(...)的方式来调用!

这边 🈶 一个猜想,假如再加持上泛型的话,是否可以创建灵活性更棒的方法,如下所示:

1
2
3
4
5
6
type SomeConstructor<T> = {
new (s: string): T
}
function fn<T>(ctor: SomeConstructor<T>): T {
return new ctor('hello1')
}

这里我们创建了一个泛型类型SomeConstructor,可以通过定义一class,只要这个class满足对应的构造函数格式的话,即可调用,如下代码所示:

1
2
3
4
5
6
class MyClass {
constructor(s: string){
console.info(`MyClass: ${s}`)
}
}
const instance = fn(MyClass)

这里我们通过创建一个与SomeConstructor类型相近的class,也就是并实现同样格式的构造方法,即可实现将class的构造调用隐藏在fn函数中,可类似于工厂方法的方式来通过传入构造函数类型创建对应的实例对象!

avatar
Genglin Zheng
原来从事安卓开发,后转从事 WEB 开发,主要开发语言 java, javascript, 熟悉使用 vue2、vue3、typescript、nuxt2、nuxt3、tailwindcss、react、react-native、nodejs 等主流框架语言
Follow Me
公告
欢迎您阅读我的博客~