当前位置:   article > 正文

【Harmony Dev】一、TypeScript学习——React+TypeScript_deveco调试typescript

deveco调试typescript

1. 前言

鸿蒙开发中,可以使用eTs语言进行程序的开发,而这就需要用到TypeScript语法了,所以还是有必要来了解下关于TypeScript语言的相关语法。当然,使用eTs开发的鸿蒙应用的时候,也对开发IDEAAPI版本有对应要求,如下:

请使用DevEco Studio V3.0.0.601 Beta1及更高版本。
使用模拟器运行时请选择API 7及以上的设备。

当然,这都是后话。在本篇文章中不涉及到鸿蒙应用的开发。

2. TypeScript

2.1 环境搭建

2.1.1 方式一

鉴于之前学过一些React,这里就使用React+typeScript来进行项目的搭建,关于react可以参考之前的博客,地址。执行如下命令进行安装配置:

npx create-react-app my-demo
cd my-demo
npm start
  • 1
  • 2
  • 3

然后,配置typescript。首先安装到项目中:

npm install typescript
  • 1

然后,我们需要配置下build命令在package.json中,即:

"scripts": {
    "build": "react-scripts build & serve -s build",
}
  • 1
  • 2
  • 3

然后通过npx tsc --init命令来生成tsconfig.json配置文件。打开tsconfig.json配置,修改如下:

 "compilerOptions": {
    "rootDir": "src",
    "outDir": "build",
}
  • 1
  • 2
  • 3
  • 4

然后,可以在src目录下创建对应的tsx文件:

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'

interface Hello {
  say(): void
}

// 继承
class App extends React.Component implements Hello {
  say(): string {
    return 'Hello World!'
  }
  render() {
    return (
      <>
        <div>{this.say()}</div>
      </>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

之后,通过npm run build就可以运行项目了。运行结果如下图:
在这里插入图片描述
参考文档:链接地址

2.1.2 方式二

参考文档:链接地址
这里就不使用这种方式了。

2.2 语法基础

文档地址:https://www.tslang.cn/docs/handbook/basic-types.html

2.2.1 类型

基础类型:

类型关键字取值示例注释
布尔booleantrue/falselet a: boolean = false;
数字number数值类型let a:number = 12JavaScript一样,TypeScript里的所有数字都是浮点数。且支持十进制、十六进制、二进制和八进制字面量。
字符串stringlet a:string='123'
数组[]let a:string[]=[1,2,3]
元组let a:[number, string] = [10, "20"]
枚举enumenum Color {RED=1, GREEN=2, BLUE=3}使用:let a:Color = Color.BLUE
Anyany不确定类型let a:any[] = [1, "123", true]
Voidvoid没有类型let a:void=null声明为void类型只能赋值为undefinednull
NullUndefinednullundefinedlet a:null = null没多大意义

类型断言:

let someValue: any = "this is a string";
// 方式一
let strLength: number = (<string>someValue).length;
// 方拾二
let strLength: number = (someValue as string).length;
  • 1
  • 2
  • 3
  • 4
  • 5

从上面可以看出,也就是类型转换。

2.2.2 接口和类

也是使用interface关键字来进行声明。

2.2.2.1 可选属性

比如下面的案例:

interface Hello {
  say(): void
  username: string
  age?: number
}

// 继承
class App extends React.Component implements Hello {
  username: string = '李四'
  age?: number | undefined
  say(): string {
    return 'Hello React typescript!'
  }
  render() {
    return (
      <>
        <div>
          user {this.username} say {this.say()}
        </div>
      </>
    )
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

可以看到在接口中定义了方法和属性,对应的还有一个age?属性,这表示为可选属性,也即是不强制复写这个age属性。在终端运行npm run build可看见效果:
在这里插入图片描述

2.2.2.2 只读属性

使用readonly来进行声明,必须在声明时或者在构造函数中被初始化。比如下面的案例:

interface Hello {
  say(): void
  readonly username: string
  age?: number
}

// 继承
class App extends React.Component implements Hello {
  username: string = '李四'
  age?: number | undefined
  say(): string {
    this.username = '张三'
    return 'Hello readonly!'
  }
  render() {
    return (
      <>
        <div>
          user {this.username} say {this.say()}
        </div>
      </>
    )
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

运行后,发现username其实并没有被二次修改成功。如下:
在这里插入图片描述

2.2.2.3 返回类型

在上面的案例中,仅使用了void来进行返回,如果想返回一个Entry对象呢?比如:

class Entry {
  name: string
  age?: number

  constructor(name: string) {
    this.name = name
  }
}

interface Hello {
  say(): Entry
  readonly username: string
  age?: number
}

// 继承
class App extends React.Component implements Hello {
  username: string = '李四'
  age?: number | undefined
  say(): Entry {
    this.username = '张三'
    return new Entry(this.username)
  }
  render() {
    return (
      <>
        <div>
           user {this.username} say {this.say().name}
        </div>
      </>
    )
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

结果:
在这里插入图片描述
很有意思的结果。也就是说其实在复写的say方法中,在这个方法的作用域中,username是被二次修改赋值了的,但是在外面的作用域中却没有被修改成功。

2.2.2.4 访问修饰符

在上面的案例中我们并没有指定其访问修饰符,因为在Typescript中默认都是public的,当然也可以使用privateprotected来进行修饰,其作用域分别为本类、和本类及派生类。

2.2.2.5 get和set

在上面的案例中,我们使用实例.的方式来进行赋值和使用,有些时候是不方便的,可能需要一些额外的校验。所以可以提供对应的getset方法来进行一些处理,比如将上面的案例进行修改:

class Entry {
  private _name: string

  constructor(name: string) {
    this._name = name
  }

  get name(): string {
    return this._name
  }

  set name(val: string) {
    this._name = val
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
2.2.2.6 静态属性

类似的,使用static进行修饰。比如:

// 定义
class Entry {
  static TAG: string = 'EntryTag'
  ...
}
// 使用
<div>
user {this.username} say {this.say().name}, tag {Entry.TAG}
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
2.2.2.7 抽象

使用abstract定义

2.2.3 函数

具名函数、匿名函数和箭头函数:

say(): Entry {
  this.username = '张三'
  return new Entry(this.username)
}
say2 = function () {
  return '123'
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

定义可选参数:

say2 = function (arg1: string, arg2?: string, arg3 = '123') {
  return arg1
}
  • 1
  • 2
  • 3

可以使用?号,也可以使用默认赋值方式。当然,当不知道有多少个参数需要传入的时候,可以使用...,比如:

say2 = function (
  arg1: string,
  arg2?: string,
  arg3 = '123',
  ...args: string[]
) {
  return arg1 + ' ' + args.join(' ')
}

// 调用
this.say2('Hello', '123', '234', '12', '13', '23', '24')}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

了解过js的都知道,在函数中存在this指向问题。比如下面的案例:

say2 = function (arg1: string) {
  return function(){
      alert(this);
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述
根据提示进行修复,即:

say2 = function (arg1: string) {
  return () =>{
      alert(this);
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5

但,其实还是错误的,如下:
在这里插入图片描述
然后再次按照提示将匿名函数转换为箭头函数,即:

say2 =  (arg1: string) => {
  return () =>{
      alert(this);
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5

此时就能够解决this的指向问题。为了能看到运行结果,最终改造为:

class App extends React.Component {
  say2 = (arg1: string): (() => string) => {
    return ():string => {
      alert(this)
      return '123'
    }
  }

  render() {
    return (
      <>
        <div>{this.say2('Hello')()}</div>
      </>
    )
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2.2.4 其他

其余部分可参考文档查阅。

2.3 练习

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/327380
推荐阅读
相关标签
  

闽ICP备14008679号