TypeScript 开发实战
梁宵
搜狗营销事业部高级架构师
34174 人已学习
新⼈⾸单¥59
课程目录
已完结/共 47 讲
TypeScript 开发实战
登录|注册
留言
18
收藏
沉浸
阅读
分享
手机端
回顶部
当前播放: 09 | 函数相关知识点梳理
00:00 / 00:00
高清
  • 高清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.75x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看
01 | 重塑“类型思维”
02 | 类型基础(1):强类型与弱类型
03 | 类型基础(2):动态类型与静态类型
04 | 编写你的第一个TypeScript程序
05 | 基本类型
06 | 枚举类型
07 | 接口(1):对象类型接口
08 | 接口(2):函数类型接口
09 | 函数相关知识点梳理
10 | 类(1):继承和成员修饰符
11 | 类(2):抽象类与多态
12 | 类与接口的关系
13 | 泛型(1):泛型函数与泛型接口
14 | 泛型(2):泛型类与泛型约束
15 | 类型检查机制(1):类型推断
16 | 类型检查机制(2):类型兼容性
17 | 类型检查机制(3):类型保护
18 | 高级类型(1):交叉类型与联合类型
19 | 高级类型(2):索引类型
20 | 高级类型(3):映射类型
21 | 高级类型(4):条件类型
22 | ES6与CommonJS的模块系统
23 | 使用命名空间
24 | 理解声明合并
25 | 如何编写声明文件
26 | 配置tsconfig.json(1):文件选项
27 | 配置tsconfig.json(2):编译选项
28 | 配置tsconfig.json(3):工程引用
29 | 编译工具:从ts-loader到Babel
30 | 代码检查工具:从TSLint到ESLint
31 | 使用Jest进行单元测试
32 | 创建项目
33 | 组件与类型(1):函数组件与类组件
34 | 组件与类型(2):高阶组件与Hooks
35 | 事件处理与数据请求
36 | 列表渲染与路由
37 | Redux与类型
38 | 搭建服务端开发环境
39 | 列表的CRUD
40 | 导出Excel
41 | 搭建Vue开发环境
42 | 组件封装
43 | 组件发布
44 | 共存策略
45 | 宽松策略
46 | 严格策略
47 | 结课测试&结束语
本节摘要
登录 后留言

全部留言(18)

  • 最新
  • 精选
极客时间
主要讲了定义函数类型的三种方式 1、使用变量的方式 2、使用type(类型别名) 3、使用inerface (接口) 使用interface还可以定义混合类型,俗称类库,这个类型的变量既可以当做函数使用,并且其本身还有一些属性或者方法,类似jquery的$使用方式。 但是使用interface定义混合类型(类库): 需要注意,其第一个行或者第一个属性必须是一个匿名函数。 形式如下: interface App{ ():void, dosomething():void, version:string } 后面如果使用这个类型定义变量的话,一般需要类型断言,使用as。 使用如下: let app:App = (()=>{}) as App; app.version = 1.0; app.dosomething = ()=>{}; 这个过程可以封装成一个工厂函数: function getapp(){ let app:App = (()=>{}) as App; app.version = 1.0; app.dosomething = ()=>{}; return app } let app = getapp() 这里有个疑问:我看文档type是类型别名的意思,type和interface在使用场景上有啥区别呢?

作者回复: type:不创建新的类型,只是给一个类型起一个名字,比如联合类型,写起来不方便,用type定义后就很简洁,你可以把type当做一种快捷访问方式; interface:创建新的类型,接口之间还可以继承(type不可以)。如果可能,建议优先使用 interface。 另外纠正你的一个理解,接口中的属性没有顺序之分,混合接口不需要第一个属性是匿名函数。

2019-07-22
8
极客时间
在C++或者java等静态语言中,两个函数名称相同,但是参数类型不同或者参数个数不同,实现了函数重载。 函数重载的好处是:不需要为功能相似的函数起不同的名称。 ts实现函数重载的时候,要求定义一系列的函数声明,在类型最宽泛的版本中实现重载,最宽泛的版本个人理解应该是,参数是any类型 返回值是any类型,如下 ``` function add8(...rest: any[]): any { let first = rest[0]; if(typeof first === 'string') { return rest.join('') } if(typeof first === 'number') { return rest.reduce((pre, cur) => pre + cur) } } ``` 这里有个疑问? 如果这样调用会报错吗 add8(),不传递任何参数 如果不报错,为什么呢? add8(...rest: any[]) 这样定义函数是否包含了未传参数的情况呢?

作者回复: 剩余参数表示参数个数不确定,不传是可以的,函数返回的是 undefined。可以加入判断 undefined 的逻辑: if (typeof first === 'undefined') { throw new Error('No param') }

2019-07-24
6
洛河
这个重载,没有前面的两个声明,应该也是可以的。前面的两个声明的意义是什么呢?

作者回复: TS在编译的时候要做类型检查,如果没有前面的函数声明,就会由于参数是 any 类型而忽略类型检查,这样类型检查的工作就转移到了运行时环境了,而这不符合TS的设计目标。 TS在处理重载时,回去查询声明列表,并且尝试使用第一个声明的类型定义,如果匹配就使用,如果不匹配就继续向后查询。

2020-10-03
2
4
TechCheng
function add8(...rest: number[]): number; function add8(...rest: string[]): string; function add8(...rest: number[] | string[]): number | string { let first = rest[0] if (typeof first === 'string') { return rest.join('') } if (typeof first === 'number') { return rest.reduce((pre, cur) => pre + cur) } } console.log(add8(1,2,3)) 为啥会报错

作者回复: 函数重载一般在实现时用any类型,如果一定要这么些,有两个报错要处理: 1)返回值类型加上undefined 2)第二个分支,给rest加上类型断言 (rest as number[]),ts只推断了first,rest类型还是 number[]|string[],不符合reduce的接口声明

2019-08-13
2
4
kevinInsight
请教下老师: let addFun:(a:number,b:number)=>number 这种函数定义的方式,在实际调用的时候该怎么使用?

作者回复: 这是函数类型的定义,调用前还需要有实现,比如:addFun = (a, b) => a + b; 然后再调用:addFun(1, 2)

2019-08-25
1
uinging
有一个小点, arr.reduce() 方法视频里并没有传入初始值, 这样在空数组的时候会报错. 传入初始值 0 就好了.

作者回复: if (typeof first === 'number') 已经保证了rest 不会是空数组

2019-08-18
2
1
安冬
听到函数重载时,也遇到参数为空时的困惑,当时是这样处理的: ```typescript function MySum(...rest: number[]): number; function MySum(...rest: string[]): string; function MySum(...rest: any[]): any { return typeof rest[0] === 'number' ? rest.reduce((pre, cur) => (pre + cur)) : typeof rest[0] === 'string' ? rest.join("") : undefined; } console.log( MySum(1, 2, 3, 4, 5) ); // 15 console.log( MySum('1', '2', '3', 'a', 'b') ); // 123ab console.log( `MySum() = ${MySum()}` ); // MySum() = undefined ``` 另外想请教老师,TypeScript 中是否不要求使用分号结尾?视频中好像都没作特别要求?

作者回复: 视频中没有处理参数未定义的情况,你这样处理可以。 ts中对分号结尾没有要求,这个全看个人风格。

2019-08-14
1
lf
function sum6(a:number, b=2, c:number, d=4) { return a+b+c+d } console.log(sum6(undefined, undefined, 3), 'sum6(1, undefined, 3)') // 10 1 + 3 + 4 第一个参数为undefined,不报错,这是因为之前说的,undefined是所有类型的子集的原因吗?

作者回复: 第一个参数是undefined应该报错,仔细看一下,或重启一下VSCode

2019-11-13
Its me
老师,函数的重载部分我有一些疑问 为什么要多余的定义两个函数呢 function add8(...rest: number[]): number function add8(...rest: string[]): string 直接定义一个 function add8(...rest: any[]): any 不是就可以实现函数的重载了吗 而且我从TypeScript的官网编译结果来看,没有丝毫差别呀 编译结果如下: function F4() { var rest = []; for (var _i = 0; _i < arguments.length; _i++) { rest[_i] = arguments[_i]; } var first = rest[0]; if (typeof first === 'number') { return rest.reduce(function (pre, cur) { return pre + cur; }); } if (typeof first === 'string') { return rest.join(','); } }

作者回复: 为啥用函数重载,请见本节我对 火云邪神0007 的回复。 因为不是很方便,函数重载在实际应用中使用的比较少,一般会用联合类型或泛型代替。 另外,函数重载的声明只用于类型检查阶段,在编译后会被删除。

2019-08-28
火云邪神0007
// function add3(...rest: number[]): number // function add3(...rest: string[]): string function add3(...rest: any[]): any { if(typeof rest[0] === 'number') return rest.reduce((pre, cur) => pre + cur) if(typeof rest[0] === 'string') return rest.join('') } document.getElementById('app').innerHTML = add3(1, 2, 3, 4, 5).toString() 老师,这样也跑的通,是不是没必要写前面的number和string的定义啊

作者回复: 我们的目的不是为了跑通,而要理解函数重载的意义,前两条声明是重载,目的是将参数类型约束为 number 或 string;最后的实现不是重载,要遵循前面的声明,比如传 boolean 就不可以了。

2019-08-21
收起评论