Typescript类型使用有什么好处,规范及应用都有哪些
Admin 2022-09-05 群英技术资讯 285 次浏览
使用Typescript可以大大提高代码的可靠程度。
强类型:语言层面限制函数的实参类型必须与形参类型相同
弱类型:语言层面不会限制实参的类型
由于这种强弱类型之分根本不是某一个权威机构的定义,所以导致后人对这种鉴定方式的细节,出现了不一致的理解。但整体上大家的鉴定方式都是在描述强类型有更强的类型约束,而弱类型中几乎没有什么约束。
强类型语言中不允许有任意的隐式类型转换,而弱类型语言中则允许任意的数据隐式类型转换。
强类型不允许随意的隐式类型转换,而弱类型则是允许的。
变量类型允许随时改变的特点,不是强弱类型的差异。
JavaScript就是动态型语言,而且变量的类型随时可以改变。
常用编程语言:
JavaScript是弱类型且动态类型,甚至可以说它没有类型。它的特征就是[任性]、[不靠谱],缺失了类型系统的可靠性。
JavaScript没有编译环节
大规模应用下,弱类型/动态类型这种优势就变成了短板。
弱类型的问题:君子约定有隐患,强制要求有保障。
强类型的优势:
//@flow
function sum(a: number, b: number) {
return a + b
}
console.log(sum(10, 20));
console.log(sum('10', '20'));
Flow只是一个小工具。
安装:flow-bin
通过编译除注解
flow开发者工具:flow language support
类型注解
function add(a:number,b:number){
return a+b
}
let num:number = 90
function foo():void{}
flow原始类型
const a: string = 'foobar'
const b: number = Infinity // NaN // 100
const c: boolean = false // true
const d: null = null
const e: void = undefined
const f: symbol = Symbol()
flow数组类型
const arr1: Array<number> = [1, 2, 3]
const arr2: number[] = [1, 2, 3]
// 元组
const foo: [string, number] = ['foo', 100]
flow对象类型
const obj1: { foo: string, bar: number } = { foo: 'string', bar: 100 }
const obj2: { foo?: string, bar: number } = { bar: 100 }
const obj3: { [string]: string } = {}
obj3.key1 = 'value1'
obj3.key2 = 'value2'
flow函数类型
//@flow
function foo (callback: (string, number) => void) {
callback('string', 100)
}
foo(function (str, n) {
// str => string
// n => number
})
flow特殊类型
// 字面量类型
const a: 'foo' = 'foo'
const type: 'success' | 'warning' | 'danger' = 'success'
// ------------------------
// 声明类型
type StringOrNumber = string | number
const b: StringOrNumber = 'string' // 100
// ------------------------
// Maybe 类型
const gender: ?number = undefined
任意类型 Mixedany
//@flow
// string | number | boolean | ....
function passMixed (value: mixed) {
if (typeof value === 'string') {
value.substr(1)
}
if (typeof value === 'number') {
value * value
}
}
passMixed('string')
passMixed(100)
// ---------------------------------
function passAny (value: any) {
value.substr(1)
value * value
}
passAny('string')
passAny(100)
任何一种JavaScript运行环境都支持。功能更为强大,生态也更健全、更完善。
Typescript是JavaScript的超集。
微软自研的开发工具对Typescript支持特别好。
Typescript(渐进式)–前端领域中的第二语言。
Typescript缺点:
使用Typescript之前要先安装依赖。
标准库就是内置对象所对应的声明。
显示中文错误信息:yarn tsc --locale zh-CN,vs-code也可以设置locale为中文
我们可以用立即执行函数/export导出模块来创建一个单独作用域。
//立即执行函数
(function () {
const a = 9
})()
//模块导出
export aa = {
a: 23
}
//原始数据类型
const a: string = 'foo'
const b: number = 100 //NaN/Infinity
const c: boolean = true //false
const d: boolean = null
const e: void = undefined
const f: null = null
const g: undefined = undefined
const h: symbol = Symbol()
并不单指普通的对象类型,而是泛指所有的非原始类型:对象、数组、函数。
//Object类型
const aa: object = function () { } //[]//{}
const obj: { foo: number, bar: string } = { foo: 123, bar: 'aaa' }
更专业的方式是使用接口。
有两种定义方式:
//数组类型
const arr: Array<number> = [1, 2, 3]
const arr1: number[] = [1, 2, 3]
是一种特殊的数据结构,其实元组就是一个明确元素数量以及每个元素类型的数组,各个元素的类型不必要完全相同。定义方式:字面量方式
//元组类型
//元组(tuple)
export { } //确保跟其他示例没有成员冲突
const tuple: [number, string] = [10, 'rock']
console.log(tuple[0]); //10
console.log(tuple[1]); //rock
//解构赋值
const [num, age] = tuple
Object.entries({
foo: 123,
zar: 432
})
enum Status {
Draft = 'aaa',
Unpulished = 'bbb',
Published = 'ccc'
}
如果确认代码中不会使用索引器去访问枚举,就可以使用常量枚举。
//常量枚举
const post = {
title: 'Hello',
content: 'TypeScript',
status: 'ok'
}
枚举类型会入侵到我们运行时的代码,它会影响到我们编译后的结果。我们在TypeScript中使用的大多数类型,它在经过编译转换后,最终都会被移除掉,因为它只是为了我们在编译过程中做类型检查,但枚举类型不会,它最终会变为一个双向键值对对象。
JavaScript中又两种函数定义方式:
函数声明
//函数声明方式
// function func1(a: number, b?: number): string {
// function func1(a: number, b: number=90): string {
function func1(a: number, ...rest: number[]): string {
return 'hello'
}
func1(12, 34)
func1(30)
使用参数可选、参数默认值、剩余参数都需要放在参数列表的最后一个参数位置。
函数表达式
//函数表达式
const func2 = (a: number, b: number) => string = function (a: number, b: number): string {
return 'func2'
}
因为any是弱类型,也是动态类型,所以TypeScript不会对any做类型检查。所以它存在类型安全问题,我们不要轻易去使用它。
function stringify(value: any) {
return JSON.stringify(value)
}
stringify('string')
stringify(123)
stringify(true)
let foo: any = 'string'
foo = 100
foo.bar()
如果我们没有通过类型注解去标注一个变量,TypeScript会根据这个变量的使用情况去推断这个变量的类型。
//隐式类型推断
let age = 10 //number
// age = 'aaa'
let foo;
foo = 45
foo = 'aaa'
虽然定义变量时如果不给它指定类型,也不给初始值,TypeScript会自动帮他注解为any类型,但还是建议定义时就注明类型。
在某些特殊情况下,TypeScript无法去推断一个变量的类型,而我们作为开发者,我们根据代码的使用情况,我们是会明确知道这个变量到底是什么类型的。类型断言的方式:
const nums = [12, 34, 56]
const res = nums.find(i => i > 10)
//断言方式一--as关键字
const num1 = res as number
//断言方式二---泛型
const num2 = <number>res
类型断言并不是类型转换,类型转换是代码在运行时的概念,而类型断言是代码在编译时的概念。当代码编译过后,断言也就不存在了。
一种规范或者一种契约。它可以用来去约定对象的结构。去使用一个接口,就必须去遵守它所有的约定。
interface Post {
title: string
content: string
}
function printPost(post: Post) {
console.log(post.title);
console.log(post.content);
}
printPost({
title: 'hello',
content: 'welcome'
})
//hello
//welcome
TypeScript中的接口只是为了我们有结构的数据,去做类型约束的,在实际运行阶段,它并没有任何意义。
interface Post {
title: string
subtitle?: string //可选成员
content: string
readonly summary: string //只读成员
}
类的特征:描述一类具体事物的抽象特征。
类可以用来描述一类具体对象的抽象成员。
ES6以前,JavaScript都是通过函数+原型模拟实现类。ES6开始,JavaScript中有了专门的class。
TypeScript增强了class的相关语法。
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}`));
}
}
类的访问修饰符(默认是public修饰符)
class Person {
public name: string // = 'init name'
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)
}
}
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 tom = new Person('tom', 18)
console.log(tom.name)
// console.log(tom.age)
// console.log(tom.gender)
const jack = Student.create('jack', 18)
类的只读属性readonly
protected readonly gender:boolean
类与接口
接口就是把共同的特征封装起来。
interface EatAndRun {
eat(food: string): void
run(distance: number): void
}
class Person implements EatAndRun {
eat(food: string): void {
console.log(`美美的吃:${food}`);
}
run(distance: number) {
console.log(`直立行走:${distance}`);
}
}
class Animal implements EatAndRun {
eat(food: string): void {
console.log(`美美的吃:${food}`);
}
run(distance: number) {
console.log(`直立行走:${distance}`);
}
}
一个接口只约束一个能力,一个类型去实现多个接口。
interface Eat {
eat(food: string): void
}
interface Run {
run(distance: number): 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}`);
}
}
抽象类与接口有点类似,也可以用来去约束子类中必须拥有某个成员。
但是抽象类可以包含一些具体的实现,但是接口只是成员的抽象,不包含具体的实现。
抽象类不能用new去实例了,只能去继承。
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(200)
泛型:我们在定义函数、接口或类时,没有指定具体的类型,等到使用时再去指定具体类型的特征。
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
}
function CreateArray<T>(length: number, value: T): T[] {
const arr = Array<T>(length).fill(value)
return arr
}
const res = CreateArray<string>(3, 'foo')
一个成员在定义时没有声明类型,在使用时单独为它做出明确声明。
import { camelCase } from 'lodash'
import qs from 'query-string'
qs.parse('?key=value&key2=value2')
declare function camelCase(input: string): string
const res = camelCase('hello')
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
今天我们来了解websocket封装的内容,下文给大家分享了websocket封装过程,及引入和使用,需要的朋友可以参考,下面我们一起来学习一下吧。
这篇文章主要介绍了Vue3 列表界面数据展示,文章主要详介绍的内容就是做的就是把打到页面的数据,带样式,也就是说好看点显示,需要的朋友可以参考一下
周日历是日常生活中不常用到的历法系统,一般用于政府、商务的会计年度或者学校教学日历中。本文将利用JavaScript制作个简单的周日历,感兴趣的可尝试一下
目录引言通用数据获取用户信息获取页面信息设置时间特定数据手动埋点上报全局自动上报组件上报总结引言上一篇我们详细介绍了前端如何采集异常数据。采集异常数据是为了随时监测线上项目的运行情况,发现问题及时修复。在很多场景下,除了异常监控有用,收集用户的行为数据同样有意义。怎么定义行为数据?顾名思义,就是用户在使用产品过程中产生
我们在用电脑浏览一些商城网站的时候,将鼠标移至商品图片就有放大查看细节的功能,很多朋友比较好奇这样放大镜的功能是怎样实现的,因此这篇文章就主要给大家分享用JS实现放大镜查看商品细节功能,实现效果的代码如下:
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008