TypeScript全解:深入对象与函数(下)

函数重载(overload)

什么是函数重载?简单来说就是同名的函数,这个概念是从 java 来的

我们来看这个需求,一个方法接受的参数有两种情况,可能是 number,可能是 string

如果用 TS 来实现,非常简单

class X {
  method(n: number | string) {
    /* ... */
  }
}

但是 java 不支持这种情况的联合类型,但是遇到这种需求该怎么办呢?java 的设计者当时又不想直接弄出这么个联合类型,那干脆让一个方法写两遍好了

class X {
  method(n: number) {
    /* ... */
  }
  method(n: string) {
    /* ... */
  }
}

于是 java 就诞生了一个新语法,一个类的方法是可以同名的,用你的参数类型和个数来判断会具体执行那个函数(很奇怪的语法吧~)

所以重载是为了解决 java 的一个问题

其实在很久之前大家都应该接触过函数重载,在 JQuery 时代的 Selector 一样

$('#div')
$(window)
$...

也许内部使用了大量的 if else,所以说 js 不需要重载这个特性,也能做出一样的效果

但是说回 TS,我认为只有这些情况可能需要用重载

一个创建日期的函数,可以接受一个数量 number,也能接受具体的日期

function createData(n: number): Date
function createData(year: number, month: number, date: number): Date
 // TODO: 注意:下面这里会和 java 稍微不同一点
function createData(a: number, b?: number, c?: number): Date { // TODO: 最后一个实现的签名需要兼容上面所有的情况
  if (a !== undefined && b !== undefined && c !== undefined) {
    return new Date(a,b,c)
  } else if (a !== undefined && b === undefined && c === undefined) {
    return new Date(a)
  } else {
    throw new Error('只接受一个或三个参数')
  }
}

也许也能用联合类型➕if else 实现出来,但是重载会更优雅一点

但是我个人依然保持能不用就不用的态度看待它,就算遇到这种问题,为何非要用一个函数来解决,用两个不同名称的函数来不香么,createDataByNumber 和 createDataByYMD

其实如果你是一个库的封装者,像 JQuery 一样,把函数封装的复杂度留给自己,使用函数重载能方便使用者
但如果你是想把函数的使用权交给用户,就应该多明明几个函数提供用户任意组合使用

this

在 TS 中怎么定义 this 的类型呢?

type Person {
  name: string;
}
function fn(this: Person, word: string) { // TODO: 这个地方好奇 this 为什么会在参数上的人,请看我的 javascript-this 文章
  console.log(this.name, word)
}

fn('hi') // TODO: 报错

this 在参数上了,那么该如何调用呢?看下面几种方法:

// 强行拼凑出 person.fn()
const p: Person & { fn: typeof fn } = { name: 'jack', fn }
p.fn('hi')

// fn.call()
fn.call({ name: 'jack' }, 'hi')

// fn.apply()
fn.apply({ name: 'jack' }, ['hi'])

// fn.bind()
fn.bind({ name: 'jack' })('hi')

... 与 参数

剩余参数

function sum(...x: number[]) {
  return x.reduce((a,b) => a + b, 0)
}

sum(1)
sum(1,2,3,4,5)
sum(1,2,3,4,5,6,7,8,9)

展开参数

function sum(name: string, ...rest: number[]) {
  fn(...rest)
  // or
  fn.apply(null, rest)
}

function fn(...x: number[]) {
  console.log(x)
}

as const

我们知道 TS 有自动推导

let a = 'hi'

此时我们很容易看出来 a 的类型是 string
其实这样可能会有些问题
理论上来说 a 的类型应该可能是 'hi' 或者 string
但是这个 TS 怎么知道我们这个 a 是常量(即类型为 'hi')还是 string 呢?

用 const

let a = 'hi' as const

不对啊,直接用 const 关键词不就好了

const a = 'hi'

其实大多数的应用场景在对象上,因为 JS 的 const 就是残废

const array = [1, 'hi'] as const

参数对象的析构

type Config = {
  url: string;
  method: 'GET' | 'POST' | 'PATCH';
  data?: number;
}

// 使用一
function ajax({ url, method, ...data }: Config) {}

// 使用二
function ajax({ url, method, ...data }: Config = {url: '', method: 'GET'}) {}

// 使用三
function ajax({ url, method, ...data } = {url: '', method: 'GET'} as Config) {}

void

function f1(): void {
  return
}
function f2(): void {
  return undefined
}
function f3(): void {
}
function f4(): void {
  return null // TODO: 报错
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容