首页 > 其他分享 >TypeScript 语言

TypeScript 语言

时间:2023-01-04 19:22:45浏览次数:50  
标签:TypeScript const 语言 number 类型 100 string

1.类型安全:强类型 vs 弱类型

强类型:语言层面限制函数的实参类型必须与形参类型相同,不允许任意的隐式类型转换,Python

弱类型:语言层面不会限制实参的类型,允许任意的隐式类型转换,JavaScript

2.类型检查:静态类型 vs 动态类型

静态类型:一个变量声明时它的类型就是明确的,声明过后类型就不允许再修改,Java。

动态类型:运行阶段才能明确变量类型,而且变量的类型也可以随时发生变化,它的变量是没有类型的,变量中存放的值是有类型的,JavaScript。

3.弱类型的问题

君子约定有隐患,强制要求有保障

// ex1: 只有运行到obj.foo()这行代码的时候才会报错
const obj = {}
// obj.foo()
// TypeError: obj.foo is not a function

// ex2: 没有按照约定传入数字,而是传入字符串,就会变成字符串拼接
function sum(a, b) {
  return a + b
}
console.log(sum(100, 100)) // 200
console.log(sum(100, '100')) // 100100

// ex3: obj的键会自动转为字符串后再使用
const obj1 = {}
obj1[true] = 100
console.log(obj1[true]) // 100
console.log(obj1['true']) // 100

4.强类型的优势

  • 错误更早的暴露

  • 代码更智能,编码更准确

  • 重构更牢靠

  • 减少不必要的类型判断

5.Flow 快速上手

  • 安装: yarn run flow

  • 初始化一个config文件:yarn run flow

  • 执行flow命令:yarn flow

  • 示例代码,文件首行必须加注释@flow,变量后加冒号和类型的方式,叫类型注解

// @flow
function sum (a: number, b: number) {
  return a + b
}
sum(100, 100)
sum('100', '100')
  • 执行结果:

6.Flow 编译移除注解

使用node 运行上面的示例,会报错

因为标准的JavaScript语法不识别类型注解(a: number)的写法,所以要自动移除掉类型注解。

解决办法一:

  • 安装remove插件:yarn add flow-remove-types --dev

  • 运行remove命令:yarn flow-remove-types . -d dist,第一个参数.表示当前目录下的文件,-d后的参数,表示输出到dist文件夹下

  • 结果

解决办法二:

  • 安装 babel:yarn add @babel/core @babel/cli @babel/preset-flow --dev

  • 添加 .babelrc 文件

{
  "presets": ["@babel/preset-flow"]
}
  • 运行命令 yarn babel .\02-getting-started.js -d dist

  • 结果

在vsCode开发工具中可以安装 FLow Language Support 辅助插件

7.Flow 类型推断

8.Flow 类型注解

// @flow
function sum (a: number, b: number) {
    return a + b
}

// 变量类型注解
let num: number = 100
num = 'string'

// 返回值类型注解
function add(a, b): number {
    return a + b
}

9.Flow 原始类型

/**
 * 原始类型
 * @flow
 */
const a: string = 100
const b: number = Infinity // NaN // 100
const c: boolean = true // false
const d: null = null
const e: void = undefined
const f: symbol = Symbol()

10.Flow 数组类型

// @flow
const arr1: Array<number> = [1, '1']
const arr2: number[] = [1, '1']
// 固定长度数组(元组)
const foo: [string, number] = ['foo', 100, 10]

11.Flow 对象类型

// @flow
const obj1: {foo: string, bar: number} = { foo: string, bar: 100 }
// 可选参数
const obj2: {foo?: string, bar: number} = { bar: 100 }
// 限制键和值的类型都必须是字符串
const obj3: { [string]: string } = {}
obj3['aa'] = 100

12.Flow 函数类型

13.Flow 特殊类型

// @flow
// 字面量类型
const a: 'foo' = 'foo'
a = 'bar'

const type: 'success' | 'warning' | 'danger' = 'success'

const b: string | number = 'string' // 100

type StringOrNumber = string | number
const c: StringOrNumber = 100

// Maybe类型:number|null|void|undefined
const gender: ?number = null

14.Flow Mixed 与 Any

// @flow
// mixed也就是所有类型的联合类型:string|number|boolean|......
// 强类型
function passMixed(value: mixed) {
    value.substr(1)
    value * value
}
passMixed('string')
passMixed(100)

// any也是所有类型的联合类型:string|number|boolean|......
// 弱类型
function passAny(value: any) {
    value.substr(1)
    value * value
}
passAny('string')
passAny(100)

mixed报错解决办法

function passMixed2(value: mixed) {
    if (typeof value === 'string') {
        value.substr(1)
    }
    if (typeof value === 'number'){
        value * value
    }
}

15.Flow 类型手册

https://www.saltycrane.com/cheat-sheets/flow-type/latest/

16.TypeScript 快速上手

  • 安装:yarn add typescript --dev

  • 运行:yarn tsc 11-getting-started.ts

  • 结果:生成降级的同名文件

修改为类型注解方式,类型不匹配时可以直接提示错误,运行tsc命令也会报错:

17.TypeScript 配置文件

  • 初始化配置文件 yarn tsc --init生成tsconfig.json文件

  • 修改tsconfig.json配置文件中的"rootDir": "src",

  • 新建src文件夹,在文件夹下修改01-getting-started.ts文件

  • 因为配置文件默认开启的严格模式,所以会提示无法推断hello1变量的类型,指定类型

  • 修改配置文件tsconfig.json

"sourceMap": true,
"outDir": "dist",
  • 运行 yarn tsc

  • 结果:

18.TypeScript 原始类型

const a: string = 'foo'
const b: number = 100 // NaN // Infinity
const c: boolean = false // true
// 以上三种类型可以赋值为null, 需要关闭严格模式: "strict": false
const d: string = null

const e: void = undefined // null,严格模式下只能是 undefined
const f: null = null
const g: undefined = undefined

19.TypeScript 作用域问题

定义一个 02-primitive-types.ts 中定义过的变量,就会出现以下报错,因为都是定义在全局作用域中

解决办法:

// 解法一: 放在一个立即执行的函数中
(function () {
    const a: number = 100
})()

// 解法二:使用ES Modules
export {}
const a: string = '200'

20.TypeScript Object 类型

export {} // 确保跟其他示例没有成员冲突

// onject:除原始对象外的其他类型
const foo: object = function (){} // [] // {}

const obj: { foo: number, bar: string } = { foo: 123, bar: 'string' }

21.TypeScript 数组类型

const arr1: Array<number> = [1, 2, 3]
const arr2: number[] = [1, 2, 3]

// 强类型的优势示例
function sum(...args: number[]) {
    return args.reduce((prev, current) => prev + current, 0)
}
sum(1, 2, 3)

如果传入的不是参数不是数字,就会报类型错误:

22.TypeScript 数组类型

明确长度和类型的数组

export {}

const tuple: [number, string] = [18, 'bar']
const age = tuple[0] // 18
const [age1, name] = tuple

23.TypeScript 枚举类型

export {}

// status 只能取0 1 2 ,这时就应该使用枚举类型,以前只能使用对象模拟
const PostStatus = {
    Draft: 0,
    Unpulished: 1,
    Published: 2
}
// 现在TypeScript 直接提供了该类型
enum PostStatus1 {
    Draft = 0,
    Unpulished = 1,
    Published = 2
}
// 如果不指定枚举值,默认从0开始
enum PostStatus2 {
    Draft,
    Unpulished,
    Published
}
// 指定了第一项,后面的值在第一项的基础上自增
enum PostStatus2 {
    Draft = 6,
    Unpulished,
    Published
}
// 如果值是字符串,因为没办法增加,只能全部指定值
enum PostStatus3 {
    Draft = 'a',
    Unpulished = 'b',
    Published = 'c'
}

const post = {
    title: 'hello TypeScript',
    content: 'TypeScript is a typed superset of JavaScript',
    // status: PostStatus.Unpulished, // 2 // 1 // 0
    status: PostStatus1.Draft
}

编译后,枚举值会以键值对的方式写在代码中,增加代码体积,所以需要enum前加上const

24.TypeScript 函数类型

export {}

function func1(a: number, b: number): string {
    return 'func1'
}
func1(100, 200) // 参数个数和类型必须相同

// 可选参数1:参数后加问号,可选参数必须放在最后
function func2(a: number, b?: number): string {
    return 'func2'
}
func2(100)
func2(100, 200)

// 可选参数2:参数加默认值,可选参数必须放在最后
function func3(a: number, b: number = 200): string {
    return 'func3'
}
func3(100)
func3(100, 200)

// 任意个数参数值
function func4(...rest: number[]): string {
    return 'func4'
}
func4(100)
func4(100, 200)

// 函数表达式方式定义, 变量func5可推断出类型
const func5 = function(a: number, b: number): string {
    return 'func5'
}
// 如果函数是回调函数,就需要使用箭头函数的方式声明类型
const func6: (a: number, b: number) => string = function (a: number, b: number) {
    return 'func6'
}

25.TypeScript 任意类型

export {}
function stringify(value: any) {
    return JSON.stringify(value)
}

stringify(100)
stringify('string')
stringify(true)
let foo: any = 'string'
foo = 100
foo.bar()

26.TypeScript 隐式类型推断

export {}
let age = 18 // 推断为number类型
// age = 'string' // 报错

let foo // 无法推断时,就是any类型
foo = 100 // 不会报错
foo = 'string' // 不会报错

27.TypeScript 类型断言

export {}
// 假定nums来自一个明确的接口
const nums = [100, 200, 300, 400]
const res = nums.find(i => i > 0)
const square = res * res
// 断言方式1:推荐
const num1 = res as number
// 断言方式2: JSX 中会冲突
const num2 = <number>res

28.TypeScript 接口

export {}
interface Post {
    title: string; // ;可以省略
    content: string
    subtitle?: string // 可选成员
    readonly summary: string // 只读成员
}
function printPost(post: Post){
    console.log(post.title)
    console.log(post.content)
}
const hello: Post = {
    title: 'TypeScript',
    content: 'hello world',
    summary: 'ts'
}
// hello.summary = '123' // 会报错,只读属性初始化后无法修改

printPost(hello)

interface Cache {
    [key: string]: string
}

const cache: Cache = {}
cache['foo'] = 'foo'

29.TypeScript 类的基本使用

描述一类具体事物的抽象特征,用来描述一类具体对象的抽象成员

export {}
class Person {
    // 必须先声明属性
    name: string
    age: number
    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }
	sayHi(msg: string): void {
        console.log(`I am ${this.name}, ${msg}`)
    }
}

30.TypeScript 类的访问修饰符

export {}
class Person {
    // 必须先声明属性
    public name: string
    private age: number
    protected gender: boolean // 可以在子类中访问
    constructor(name: string, age: number) {
        this.name = name
        this.age = age
        this.gender = true
    }

    sayHi(msg: string): void {
        console.log(`I am ${this.name}, ${msg}`)
        console.log(this.age)
    }
}
const tom = new Person('tom', 18)
console.log(tom.name) // tom
// console.log(tom.age) // 无法访问
// console.log(tom.gender) // 无法访问

class Student extends Person {
    private constructor(name: string, age: number) {
        super(name, age)
        console.log(this.gender) // 可以访问
    }
    static create (name: string, age: number) {
        return new Student(name, age)
    }
}
// const jsck = new Student('jack', 20) 不能new,只能使用静态方法创建
const jack = Student.create('jack', 20)

31.TypeScript 类的只读属性

export {}
class Person {
    // 必须先声明属性
    public name: string
    private age: number
    protected readonly gender: boolean // 只读属性
    constructor(name: string, age: number) {
        this.name = name
        this.age = age
        this.gender = true
    }

    sayHi(msg: string): void {
        this.gender = false // 提示只读属性不能修改
        console.log(`I am ${this.name}, ${msg}`)
        console.log(this.age)
    }
}

32.TypeScript 类与接口

export {}

// 建议每个接口实现一种能力
// interface EatAndRun {
//     eat(food: string): void
//     run(distance: number): void
// }
interface Run {
    run(distance: number): void
}
interface Eat {
    eat(food: string): void
}

class Person implements Eat, Run {
    eat(food: string): void {
        console.log(`优雅的进餐:${food}`)
    }
    run(distance: number) {
        console.log(`直立行走:${distance}`)
    }
}
class Animal implements Eat, Run {
    eat(food: string): void {
        console.log(`呼噜呼噜的吃:${food}`)
    }
    run(distance: number) {
        console.log(`爬行:${distance}`)
    }
}

33.TypeScript 抽象类

与接口不同的是,可以包含实现,接口不能包含实现

export {}
abstract class Animal {
    eat(food: string): void {
        console.log(`呼噜呼噜的吃${food}`)
    }
    abstract run(distance: number):void
}

class Dog extends Animal {
    run(distance: number): void {
        console.log(`爬行${distance}`)
    }
}

const d = new Dog()
d.eat('肉')
d.run(100)

34.TypeScript 泛型

定义的时候不指定类型,调用的时候再指定具体的类型

export {}
function createNumberArray(length: number, value: number): number[] {
    const arr = Array<number>(length).fill(value)
    return arr
}
function createStringArray(length: number, value: string): string[] {
    const arr = Array<string>(length).fill(value)
    return arr
}
const res = createNumberArray(3, 100) // [100, 100, 100]
// 上面的情况很冗余,用泛型来解决
function createArray<T>(length: number, value: T): T[] {
    const arr = Array<T>(length).fill(value)
    return arr
}
const res1 = createArray<string>(3, '100')
const res2 = createArray<number>(3, 100)

35.TypeScript 类型声明

使用lodash等插件

  • 安装loadsh:yarn add loadsh

  • 引入某个函数: import { camelCase } from 'lodash'

  • 提示没有类型声明:

  • 安装声明:yarn add @types/lodash

  • 或者自己针对这个函数编写声明declare function camelCase(input: string): string

标签:TypeScript,const,语言,number,类型,100,string
From: https://www.cnblogs.com/caicai521/p/17025784.html

相关文章

  • power app portal 多语言配置
    官方文档:https://learn.microsoft.com/en-us/power-apps/maker/portals/configure/enable-multiple-language-support门户中可以设置很多语言,首先需要在当前环境中启用:1......
  • C语言--常用进程间通信方式
    管道管道是一种队列型的数据结构,它的数据从一端输入,另一端输出。管道最常见应用就是连接两个进程的输入和输出,将一个进程的输入作为另一个进程的输出。shell中有专门的管......
  • C语言中使用ESL连接FreeSwitch
    前言之前在【FreeSwitch开发实践】在nodejs中用ESL连接FreeSwitch一文介绍了在NodeJS下使用ESL连接FreeSwitch,本文则对在C语言下使用ESL连接FreeSwitch作了一个系统介绍......
  • C语言--unistd.h
    在此随手记录一些unistd.h文件中的函数dup声明:intdup(intoldfd)功能:复制文件描述符,重定向输入输出返回值:成功返回当前系统可用的最小整数值,否则返回-1dup2声明:int......
  • 深入学习go语言(二):数据结构-切片
    在go语言实际开发过程,我们使用更多的是切片而不是数组,数组的固定长度注定了只能在一些特殊场景下才具有优势。切片是长度可变的,所以切片的类型只有其存储的元素类型这一个......
  • C语言printf输出彩色字体
    使用格式:样式开始+被修饰字符串+样式结束样式开始:\033[+参数1+;+参数2+;+参数3+m参数1:代表背景色可选值和含义:字背景颜色范围:40-4940:黑41:深红42:绿43:黄......
  • [Typescript] Force to valid the type by using Valid branded type
    Let'swehaveaformtosubmitnewpassword.Beforewesendrequesttoserver,wewanttoforcedevelopertovalidthepasswordbeforesendingtherequest.We......
  • RocketMQ 5.0 多语言客户端的设计与实现
    本文作者:古崟佑,阿里云中间件开发。 RocketMQ5.0版本拥有非常多新特性,比如存储计算分离、batch能力的提升等,它是具有里程碑意义的版本。提到新版本,我们往往会首先......
  • C语言数据的存储
    前言之前写过一篇关于​​C语言内存管理​​的文章,对在C语言中使用内存中需要注意的一些问题和解决办法做了一些总结。实际上,内存终归是要存储数据的,这次对C语言中的数据存......
  • RocketMQ 5.0 多语言客户端的设计与实现
    本文作者:古崟佑,阿里云中间件开发。RocketMQ5.0版本拥有非常多新特性,比如存储计算分离、batch能力的提升等,它是具有里程碑意义的版本。提到新版本,我们往往会首先想到服务......