typescript箭头函数参数_Typescript 入门基础篇(一)

685d367f-ae34-eb11-8da9-e4434bdf6706.png

Typescript 基础

Typescript是Javascript的一个超集。以下typescript简称为ts, 此文章主要是对ts官网文档的一个简化,缩短学习基础时间。

类型基础

ts 的类型主要有布尔值数字字符串数组元组枚举AnyVoidNullUndefinedNever

  # Boolean let boo : boolean = true; || let boo : boolean = false;# Number(数字和各种进制)let num : number = 6; || let num : number = 0xf00d;# Stringlet str : string = 'string';# Arraylet arr : number[] = [ 1, 2, 3];  // 此类是表示由此类元素组成的一个数组let arr : Array<number> = [ 1, 2, 3]; // 数组泛型 Array<元素类型># Tuple> 元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。let arr : [ string, number ];arr = [ 'hello', 10 ];  // okarr = [ 10, 'hello' ]; // error> 访问已知索引的元素,会得到正确的类型arr[1].slice(0);  // error, 'number' does not have 'slice';> 访问越界元素,使用联合类型替代。arr[3] = 'hello'; || arr[3] = 10;arr[4] = true;  // 不是联合类型中的一个,报错。arr[6].toString();  // ok,联合类型都具备这个方法。# enum> enum类型是对JavaScript标准数据类型的一个补充。 像C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。enum Name { 'Tom', 'Jack' }let currName : Name = Name.Tom;> 默认情况下,从0开始为元素编号。 你也可以手动的指定成员的数值。enum Name { 'Tom' = 1, 'Jack' }let currName : Name = Name.Jack;> 或全部手动赋值enum Name { 'Tom' = 1, 'Jack' = 4 }> 枚举类型提供的一个便利是你可以由枚举的值得到它的名字。enum Name { 'Tom' = 1, 'Jack' = 4 }let currName : Name = Name[4];console.log(currName); // Jack# Any> 有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用 any类型来标记这些变量:let anytype : any = 3;anytype = 'also can be string';anytype = false; > 不定类型的arraylet anyArray : any[] = [ 1, true, '123'];# Void> 某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是voidfunction warning() : void {console.log('warning');}> void的变量只能赋值为`undefined`或`null`;let unsure : void = undefined;# undefined 和 null> TypeScript里,undefined和null两者各自有自己的类型分别叫做undefined和null。let un : undefined = undefined;let nu : null = null;> 默认情况下null和undefined是所有类型的子类型。 就是说你可以把 null和undefined赋值给number类型的变量.当你指定了--strictNullChecks标记,null和undefined只能赋值给void和它们各自。 这能避免 很多常见的问题。 也许在某处你想传入一个 string或null或undefined,你可以使用联合类型string | null | undefined。# never> never类型表示的是那些永不存在的值的类型。 例如, never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never类型,当它们被永不为真的类型保护所约束时。never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。 即使 any也不可以赋值给never。function error( message : string ) : never {throw new Error(message);}function fail(){return error('something error');}function loop() : never {while (true) {}}

类型断言

有时候你会遇到这样的情况,你会比TypeScript更了解某个值的详细信息。 通常这会发生在你清楚地知道一个实体具有比它现有类型更确切的类型。

主要有两种表现形式。

  • 尖括号语法
let unsure : any = 'this is a string';let strlength : number = (<string>unsure).length;
  • as 语法
let unsure : any = 'this is a string';let strlength : number = (unsure as string).length;

变量声明

这里不做多讲,只摘出必要部分,用一个示例来区分var和let
# 分析下列代码结果for (var i = 0; i < 10; i++) {setTimeout(function() { console.log(i); }, 100 * i);}// 10 10 10 10 10 10 10 10 10 10 for (var i = 0; i < 10; i++) {(function(i) {setTimeout(function() { console.log(i); }, 100 * i);})(i);}// 0 1 2 3 4 5 6 7 8 9for (let i = 0; i < 10 ; i++) {setTimeout(function() {console.log(i); }, 100 * i);}// 0 1 2 3 4 5 6 7 8 9
const 在这里不做多说,和JS是无区别的。

解构

这里主要说一下解构声明类,如果对解构不了解的可以先了解一下解构。
# 对于函数参数function arg([ fir, sec ] : [ number, number ]) :void {console.log( fir, sec );}let input : Array<number> = [ 1, 2 ];arg(input);# 属性重命名let { a : name1 , b : name2 } : { a : string, b : number }= { a : 'a' , b : 100 };# 默认值function default( defaultObj : { a : string, b : number } ) : void {let { a , b  = 100 } = defaultObj;}
这里单说一下不声明的赋值需要用括号括起来,不然一对花括号会被解析成一个块。
( { a, b } : { a : string, b : number } = { a : 'a', b: 100 } );
扩展对象的一些小问题,它仅包含对象 自身的可枚举属性。 大体上是说当你展开一个对象实例时,你会丢失其方法:TypeScript编译器不允许展开泛型函数上的类型参数。 这个特性会在TypeScript的未来版本中考虑实现。

接口

intro

TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

需要注意的是,我们传入的对象参数实际上会包含很多属性,但是编译器只会检查那些必需的属性是否存在,并且其类型是否匹配。 然而,有些时候TypeScript却并不会这么宽松
# 简例interface LabelledValue {label : string};function printLabel (labelledObj : labelledValue) : void {console.log( labelledObj.label );}let myObj = {size: 10, label: "Size 10 Object"};printLabel(myObj);> 类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。# 可选属性interface SquareConfig {color?: string;width?: number;}function createSquare(config: SquareConfig): {color: string; area: number} {let newSquare = {color: "white", area: 100};if (config.color) {newSquare.color = config.color;}if (config.width) {newSquare.area = config.width * config.width;}return newSquare;}let mySquare = createSquare({color: "black"});# 只读属性一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 readonly来指定只读属性:interface Point {readonly x: number;readonly y: number;}TypeScript具有ReadonlyArray<T>类型,它与Array<T>相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改:let a: number[] = [1, 2, 3, 4];let ro: ReadonlyArray<number> = a;> readonly vs const 做为变量使用的话用 const,若做为属性则使用readonly。# 额外属性检查interface SquareConfig {color?: string;width?: number;}function createSquare(config: SquareConfig): { color: string; area: number } {// ...}1 类型断言let mySquare = createSquare({ width: 100, opacity: 0.5 } as SquareConfig);2 添加字符串索引签名,这种是你前提可以确定这个对象可能具有某些特殊用途的额外属性。interface SquareConfig {color?: string;width?: number;[propName: string]: any;}# 函数类型为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。interface SearchFunc {(source: string, subString: string): boolean;}创建一个函数类型的变量,并将一个同类型的函数赋值给这个变量let mySearch: SearchFunc;mySearch = function(source: string, subString: string) : boolean {let result = source.search(subString);return result > -1;}函数的参数会逐个进行检查,要求对应位置上的参数类型是兼容的。但函数的参数名不需要与接口里定义的名字相匹配。# 可索引的类型可索引类型具有一个 索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。 interface StringArray {[index: number]: string;}let myArray: StringArray;myArray = ["Bob", "Fred"];let myStr: string = myArray[0];共有支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。 这是因为当使用 number来索引时,JavaScript会将它转换成string然后再去索引对象。 也就是说用 100(一个number)去索引等同于使用"100"(一个string)去索引,因此两者需要保持一致。class Animal {name: string;}class Dog extends Animal {breed: string;}// 错误:使用数值型的字符串索引,有时会得到完全不同的Animal!interface NotOkay {[x: number]: Animal;[x: string]: Dog;}字符串索引签名能够很好的描述dictionary模式,并且它们也会确保所有属性与其返回值类型相匹配。 因为字符串索引声明了 obj.property和obj["property"]两种形式都可以。interface NumberDictionary {[index: string]: number;length: number;    // 可以,length是number类型name: string       // 错误,`name`的类型与索引类型返回值的类型不匹配}索引签名可以设置为只读,这样可以防止给索引赋值interface ReadonlyStringArray {readonly [index: number]: string;}let myArray: ReadonlyStringArray = ["Alice", "Bob"];myArray[2] = "Mallory"; // error!# 类类型1. 简例interface ClockInterface {currentTime: Date;}class Clock implements ClockInterface {currentTime: Date;constructor(h: number, m: number) { }}接口描述了类的公共部分,而不是公共和私有两部分。 它不会帮你检查类是否具有某些私有成员。2. 类静态部分与实例部分的区别当你操作类和接口的时候,你要知道类是具有两个类型的:静态部分的类型和实例的类型。当一个类实现了一个接口时,只对其实例部分进行类型检查。 constructor存在于类的静态部分,所以不在检查的范围内。我们应该直接操作类的静态部分。interface ClockConstructor {new (hour: number, minute: number): ClockInterface;}interface ClockInterface {tick();}function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {return new ctor(hour, minute);}class DigitalClock implements ClockInterface {constructor(h: number, m: number) { }tick() {console.log("beep beep");}}class AnalogClock implements ClockInterface {constructor(h: number, m: number) { }tick() {console.log("tick tock");}}let digital = createClock(DigitalClock, 12, 17);let analog = createClock(AnalogClock, 7, 32);3. 继承接口和类一样,接口也可以相互继承。 这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。interface Shape {color: string;}interface Square extends Shape {sideLength: number;}let square = <Square>{};square.color = "blue";square.sideLength = 10;可继承多个接口interface Shape {color: string;}interface PenStroke {penWidth: number;}interface Square extends Shape, PenStroke {sideLength: number;}let square = <Square>{};square.color = "blue";square.sideLength = 10;square.penWidth = 5.0;4. 混合类型有时你希望一个对象可以同时具有多种类型。interface Counter {(start: number): string;interval: number;reset(): void;}function getCounter(): Counter {let counter = <Counter>function (start: number) { };counter.interval = 123;counter.reset = function () { };return counter;}let c = getCounter();c(10);c.reset();c.interval = 5.0;( 在使用JavaScript第三方库的时候,你可能需要像上面那样去完整地定义类型。 )5. 接口继承类当接口继承了一个类类型时,它会继承类的成员但不包括其实现。 就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。 接口同样会继承到类的private和protected成员。 这意味着当你创建了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现(implement)。class Control {private state: any;}interface SelectableControl extends Control {select(): void;}class Button extends Control implements SelectableControl {select() { }}class TextBox extends Control {select() { }}// 错误:“Image”类型缺少“state”属性。class Image implements SelectableControl {select() { }}

举个栗子

class Greeter {greeting: string;constructor(message: string) {this.greeting = message;}greet() {return "Hello, " + this.greeting;}
}let greeter = new Greeter("world");
这里关于类的继承等一系列的不做解释,有需要的可以自行找一下类的相关定义进行补充。注:派生类(继承得来)通常被称作 子类,基类(被继承的)通常被称作 超类。

修饰符

  • 公共 public(默认)

可以自由的访问程序里定义的成员。

  • 私有 private

不能在声明它的类的外部访问。当我们比较带有 privateprotected成员的类型的时候,情况就不同了。 如果其中一个类型里包含一个 private成员,那么只有当另外一个类型中也存在这样一个 private成员, 并且它们都是来自同一处声明时,我们才认为这两个类型是兼容的。

  • 受保护 protected

protected 修饰符与private修饰符的行为很像,但是,protected成员在派生类中仍然可以访问。构造函数也可以被标记成 protected。 这意味着这个类不能在包含它的类外被实例化,但是能被继承。

  • 只读 readonly 使用readonly关键字将属性设置为只读的。只读属性必须在声明时或构造函数里被初始化。
  # 综合栗子class Parent {public name : string; // 默认是public,这里举例所以显式的写出来了。private age : number; // 只可以在Parent类内部访问protected sex : string; // 可以在基类和派生类内部访问readonly height : number; // 此时是只读的,不允许修改;constructor( name : string, age : number, sex : string = 'man' ){this.name = name;this.age = age;this.sex = sex;this.height = 180;}changeName( name : string = '' ){this.name = name;console.log( `name 改为 ${ name }` );}getAge(){console.log(`${ this.name } 的年龄为 ${ this.age }`);}getSex(){console.log(`${ this.name } 的性别为 ${ this.sex }`)}}class Son extends Parent {constructor( name : string, age : number, sex : string = 'man' ){// 派生类包含构造函数钱必须调用super(),他会执行基类的构造。而且在构造里访问this之前必须调用super();super(name,age,sex);}run(distance : number = 10){console.log(`${ this.name } run ${ distance }m`);}changeName( name : string = ''){// 重写父类的changeName方法。console.log('rewrite...');super.changeName(name);}getSonSex(){// 此处访问基类的sex属性console.log(`${ this.name } 的性别为 ${ this.sex } ~ 派生类`)}}class ProtectParent {protected constructor(){this.name = 'protected';}}// 参数属性class Argument {// 这个地方参数被声明为private类型之后会在初始化时声明赋值合并。参数属性通过给构造函数参数添加一个访问限定符来声明。 使用 private限定一个参数属性会声明并初始化一个私有成员;对于 public和 protected来说也是一样。constructor( private name : string ){}printf( time : number ){console.log( `${ this.name } call ${ time } time;` )}}let parent : Parent = new Parent('jack',50, 'woman');let son : Son = new Son('jackson',10);parent.changeName('jacks');parent.getAge();parent.age; // error,age为私有属性,只可以在Parent类中访问parent.getSex();parent.sex; // error, sex为被保护的属性,只可以在基类和派生类内部访问parent.height; // 180parent.height = 120; // error, height是只读的。son.run();let PP = new ProtectParent(); // error,构造是被保护的。// 存取器首先,存取器要求你将编译器设置为输出ECMAScript 5或更高。 不支持降级到ECMAScript 3。 其次,只带有 get不带有 set的存取器自动被推断为 readonly。 这在从代码生成 .d.ts文件时是有帮助的,因为利用这个属性的用户会看到不允许够改变它的值。let passcode = "secret passcode";class Employee {private _fullName: string;get fullName(): string {return this._fullName;}set fullName(newName: string) {if (passcode && passcode == "secret passcode") {this._fullName = newName;}else {console.log("Error: Unauthorized update of employee!");}}}
inoccent:Typescript 入门基础篇(二)​zhuanlan.zhihu.com
6a5d367f-ae34-eb11-8da9-e4434bdf6706.png

你也可以关注我的公众号: 混日子码农

6b5d367f-ae34-eb11-8da9-e4434bdf6706.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/487066.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sublime学习笔记

学习课程地址&#xff1a;快乐的sublime编辑器_sublime编辑器使用 另可参考笔记地址&#xff1a; http://c.haoduoshipin.com/happysublime/ http://blog.csdn.net/u014465934/article/details/72810763 PS&#xff1a;博主的一些文章地址&#xff1a;http://happypeter.github…

里程碑式的数学证明,攻破著名Erdős猜想中关键障碍

大数据文摘出品来源&#xff1a;wired编译&#xff1a;Canary、Andy最近&#xff0c;两名数学家解决了一个关于整数相加性质最著名猜想中的第一部分。该猜想由匈牙利传奇数学家Paul Erdős于60多年前提出&#xff0c;一个无限整数序列在何时一定会包含至少有三个等差数的模式&a…

浅复制和深复制

浅复制是由默认构造函数实现的&#xff0c;将对应数据成员一一复制。 浅复制 template<class T> Array<T>::Array(const Array<T>&a) {sizea.size;a.list list; }如果主函数中有这样的语句&#xff1a; int main() {Array<int> a(10);Array<…

admin select 2 异步_解决Angularjs异步操作后台请求用$q.all排列先后顺序问题

最近我在做angularjs程序时遇到了一个问题1.页面有很多选择框&#xff0c;一个选择框里面有众多的选择项&#xff0c;和一个默认选定的项,像下面这样(很多选择框&#xff0c;不只一个)&#xff1a;2.众多的选项要从后台接口得到&#xff0c;默认项从另一个后台接口得到&#xf…

产业|世界十大工业自动化公司,你知道几家?

来源&#xff1a;机械前线国内工业自动化行业的竞争激烈&#xff0c;国外工业自动化设备、产品制造商依然控制国内上游产品供应的主要市场&#xff0c;下面来看看国外最赚钱的工业自动化公司有哪些。▶1、德国西门子西门子股份公司(SIEMENSAGFWB:SIE&#xff0c;NYSE:SI)是全球…

12月25晚-12月29日做的两个网页

1 <!doctype html>2 <html>3 <head>4 <meta charset"utf-8">5 <title>仿山东理工大学</title>6 <link rel"stylesheet" href"css/wangye.css">7 <link href"img/favicon.ico" r…

2运行内存多大_智能设备中的内存与容量为何傻傻分不清?它们的区别是什么?...

在日常生活中&#xff0c;很多时候会把某些电子产品的容量说成内存&#xff0c;或者把内存说成了容量。比如有人问&#xff1a;“这个手机的内存多大&#xff1f;”或许会有这样回答的&#xff1a;“内存是256G。”这种问答方式虽然看似很普通&#xff0c;如果让业内人士以及了…

Nature突破:首个比头发丝还细的机器人诞生了!可用针头注射入人体

来源&#xff1a;科研大匠1959年&#xff0c;诺贝尔奖得主、理论物理学家Richard Feynman 首次提出微型医用机器人的概念。此后&#xff0c;将电子器件微型化以生产细胞大小的机器人一直是科学家们追求的目标&#xff0c;但由于缺乏合适的微米级致动器系统&#xff0c;该技术一…

腾讯云云机安装dockers

云机的配置 首先更新一下源&#xff08;更新前一直装不了&#xff09;下载dockers-ce&#xff08;社区版&#xff09;启动dockers服务使用hello-world进行测试&#xff08;由于本地没有hello-world这个镜像&#xff0c;所以dockers会下载下来并且在容器里运行&#xff09;转载于…

移动短信回执怎么开通_才知道移动积分需要主动开通功能,才会消费产生积分,垃圾!!!...

几天前朋友突然跟我说用移动积分兑换了流量&#xff0c;于是我很好奇就打开移动APP想查询下自己有多少积分&#xff0c;毕竟几年了从来没想到过积分兑换。有趣的事情发生了&#xff0c;我发现自己的积分显示是0&#xff0c;这怎么可能呢。用了好几年的号码怎么可能没有积分。当…

AIoT成功的关键要素

来源&#xff1a;中国工业和信息化本文发表于《中国工业和信息化》杂志2020年8月刊总第26期随着科技的不断发展&#xff0c;一些在功能上具有相互补充作用的技术正在不可避免地发生结合——例如&#xff0c;人工智能&#xff08;AI&#xff09;和物联网&#xff08;IoT&#xf…

中富之命能有多少钱_邯郸白铁风管工每天工资多少钱?白铁风管价格多少钱你能接受?...

邯郸白铁风管工每天工资多少钱&#xff1f;白铁风管价格多少钱你能接受&#xff1f;身为买家&#xff0c;认为白铁风管价格越低越好&#xff0c;身为厂家&#xff0c;希望在市场价格合理的情况下获得更高的利润。白铁风管工人一天的工资也是一样。以下小编就来说一下白铁风管的…

人工智能的尽头是人工?

来源&#xff1a;CAA混合智能专委会上个月出门&#xff0c;发现十字路口的交警和辅警人数明显增加了。我不禁有些诧异&#xff0c;近十年来&#xff0c;人工智能最成功和最有效的落地成果不就是安防和交通相关应用吗&#xff0c;而十字路口往往都是视频监控最密集的地方&#x…

3种团队分组适应项目_业务团队怎样做目标管理?更能激励员工?(附实操方法)...

导语&#xff1a;目标管理是业务团队的核心&#xff0c;好的目标管理激励员工&#xff0c;差的目标管理形同虚设&#xff01;很多公司有这样的现象&#xff1a;每次给业务团队订目标的时候&#xff0c;总是需要经过一番讨价还价之后&#xff0c;才能最终确定&#xff0c;然而结…

AI处理器热潮正在消退

来源&#xff1a;technews(台) 作者&#xff1a;痴汉水球俗语说得好&#xff1a;海水退潮之后&#xff0c;才知道谁没穿裤子。但历史的教训往往证明残酷的事实&#xff1a;结果站在浪里的所有人&#xff0c;全部都没有穿裤子。处理器业界的年度盛事第32届IEEE HotChips&#x…

gtj2018如何生成工程量报表_土建软件GTJ2018中的十个问题及解决方法

问题1柱汇总计算报错提示&#xff1a;直筋长度的计算结果小于0&#xff1f;方法一&#xff1a;调整为【纵筋销固】就可以计算出来钢筋量。但是设置插筋和纵筋锚固计算出来是有量差的&#xff0c;可以在编辑钢筋中把手算的长度手动添加下或者是在单构件输入界面去手动添加下。方…

重磅|我国科学家成功研制全球神经元规模最大的类脑计算机

来源&#xff1a;浙江大学9月1日&#xff0c;亿级神经元类脑计算机重大成果新闻发布会在杭州召开。浙江大学校长吴朝晖院士出席并讲话。他表示&#xff0c;人工智能浪潮正加快智能增强时代的到来&#xff0c;类脑计算机将成为未来计算的主要形态和重要平台&#xff0c;将在模拟…

java 毫秒转分钟和秒_PDF如何转换CAD文件?教你一分钟批量转上百文件方法,看完秒懂!...

如今科技这么发达&#xff0c;很多人在工作中都会遇到形形色色的各类文件。而同时也因为工作需求碰到文件格式转换难题&#xff0c;如&#xff1a;PDF如何快速转换成CAD文件&#xff1f;今天小编就教大家一个方法&#xff0c;让你轻松一秒完成百个PDF文件转CAD。具体操作方法&a…

数据库设计-规范化规则

SQL反模式一书在附录章节给出了设计关系数据库的规范化规则&#xff0c;一个简明的规范化规则清单。 关系是什么 在规范化之前&#xff0c;我们先要理解下关系。 数学中关系定义&#xff1a;两个不同数据域上的值的集合&#xff0c;通过一个条件得到的一个所有可能组合的子集。…

AI 如果 “智力爆炸” ,只有普通智力的人类是蝼蚁还是宠物?

编译&#xff5c;吴婷婷编审&#xff5c;王新凯出品&#xff5c;学术头条想象一下&#xff0c;当你推倒多米诺骨牌时&#xff0c;第一张牌倒下&#xff0c;而后每一块牌迅速产生反应&#xff0c;直至最后一块牌。实际上&#xff0c;这种连锁反应不局限于物理界&#xff0c;而是…