基本类型和拓展类型 Typescript 与 JavaScript 共享基本类型,拓展了一些类型
元组 Tuple
枚举 Enum
any和void
从不类型 never
共有基本类型 1 2 3 4 5 6 let a: number = 0 ;let b: string = "扫呗无线前端" ;let c: boolean = true ;let d: undefined = undefined ;let e: null = null ;
object 类型,统指非number, string, null, undefined, boolean等基本类型的复杂类型 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 declare function bar (arg: object | null ): number ;bar({}); bar(() => {}); bar(null ); bar(12121 ); interface demofunc { (arg: object): number } let func: demofunc = (arg): number => { return 1 } func({}); func(() => {}) func(null ); func(12121 ) func("str" ) let arr: Array <string > = ['12121212' ]; let arr1: number [] = [1 ,2 ,3 ];
元组 Tuple 元组类型允许你用固定数量的元素表示数组,这些元素的类型是已知的,但不必相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 let x: [string , number ];x = ["hello" , 10 ]; x = [10 , "hello" ]; console .log(x[0 ].substring(1 )); console .log(x[1 ].substring(1 )); x[3 ] = "world" ; console .log(x[5 ].toString());
enum 枚举 enum类型是对JavaScript标准数据类型的一个补充。 像C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。
1 2 3 4 5 6 enum Color {Red = 1 , Green = 2 , Blue = 4 }let c: Color = Color.Green;let colorName: string = Color[2 ];console .log(colorName);
枚举的应用场景适合定义一些固定的状态,比如应用得状态
1 2 3 4 5 6 7 enum status { isFetching, pendding, success, error }
any和void、从不类型never
类型断言 简略的定义是:可以用来手动指定一个值的类型。 有两种写法,尖括号和as:
1 2 3 4 let bar: any = "str" ;let len: number = (<string >bar).length;let len1: number = (bar as string ).length;
泛型 Generics 先来看一个demo
1 2 3 function demo (arg: number ): number { return arg }
demo这个函数直接返回了传入的值,这个时候确定的是number类型,所以也直接返回了number类型 软件工程的一个主要部分就是构建组件,构建的组件不仅需要具有明确的定义和统一的接口,同时也需要组件可复用。支持现有的数据类型和将来添加的数据类型的组件为大型软件系统的开发过程提供很好的灵活性。
在C#和Java中,可以使用”泛型”来创建可复用的组件,并且组件可支持多种数据类型。这样便可以让用户根据自己的数据类型来使用组件。
泛型方法 在ts里,声明泛型方法
1 2 3 function identity <T >(arg: T ): T { return arg; }
调用泛型方法
1 2 3 4 identity<string >("112121" ); identity("12121" );
泛型与any typescript的特殊类型any在使用的时候可以代替任意的类型,看似和泛型很像,但实际上有很大差别
1 2 3 4 5 6 7 8 9 function anyDemo (arg: any ):any { console .log(arg.length); return arg; } function genericsDemo <T >(arg: Array <T> ): Array <T > { console .log(arg.length); return arg; }
anyDemo, 因为arg的类型是any,所以可以打印length属性,但是如果arg的实际输入类型不是带有length属性的变量,会抛出异常
genericsDemo, 定义了arg类型是数组的泛型类型,所以一定有length属性,所以不会抛出异常
自定义类型类型 interface 与 type的区别 相同点 都可以描述一个对象或函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 interface Blog{ title: string ; } interface funcs { (name: string ): void ; } let bar:funcs = function (name ) { console .log(name) } bar("12121" ) type Blog = { title: string ; } type funcs = (name: string ) => void let bar: funcs = function (name ) { console .log(name) } bar("112121" )
拓展(extends)与 交叉类型(Intersection Types) interface是可以extends,但是type是不允许extends和implement的。但是type却可以通过交叉类型实现interface 的extends行为,并且两者并不是相互独立的,也就是说 interface 可以 extends type, type 也可以 与 interface 类型 交叉 。 虽然效果差不多,但是两者语法不同。
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 interface Name { name: string ; } interface User extends Name { age: number ; } type Name = { name: string ; } type User = Name & { age: number };type Name = { name: string ; } interface User extends Name { age: number ; } interface Name { name: string ; } type User = Name & { age: number ; }
不同点 type 可以而 interface 不行
type 可以声明基本类型别名,联合类型,元组等类型
1 2 3 4 5 6 7 8 type Name = string ;type status = string | number type arr = [string , number ]
type 语句中还可以使用 typeof 获取实例的 类型进行赋值
1 2 3 4 let div = document .createElement('div' );type B = typeof div
1 2 3 4 5 6 7 8 type StringOrNumber = string | number ; type Text = string | { text: string }; type NameLookup = Dictionary<string , Person>; type Callback<T> = (data: T ) => void ; type Pair<T> = [T, T]; type Coordinates = Pair<number >; type Tree<T> = T | { left: Tree<T>, right: Tree<T> };
interface 可以而 type 不行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 interface User { name: string age: number } interface User { sex: string }
实现与继承: implements 和 extends extends 很明显就是ES6里面的类继承,那么implements 又是做什么的?他和extends有什么不同? implements 实现。与C#或Java里接口的基本作用一样,TypeScript也能够用它来明确的强制一个类去符合某种契约
implements 基本方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 interface Bar { name: string ; age?: number ; } class bar implements Bar { name = '扫呗无限前端' ; } class bar2 implements Bar { name = '扫呗无限前端' ; age = 18 } class bar3 implements Bar { name = '扫呗无限前端' ; age = '18' }
而, extends 是继承父类,两者其实可以混用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 interface Fun { name: string ; title: string ; } interface Bar { age: number ; } class B { sex = 'man' ; } class A extends B implements Fun,Bar { name = '扫呗无限前端' ; title = 'web前端攻城狮' ; age = 18 }
声明文件与命名空间: declare 和 namespace 比如Vue项目中的 shims-tsx.d.ts 和 shims-vue.d.ts ,其初始内容是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import Vue, { VNode } from 'vue' ;declare global { namespace JSX { interface Element extends VNode {} interface ElementClass extends Vue {} interface IntrinsicElements { [elem: string ]: any ; } } } declare module '*.vue' { import Vue from 'vue' ; export default Vue; }
declare
: 当使用第三方库时,我们需要引用他的声明文件,才能获得对应的代码补全,接口提示等功能。
1 2 3 4 5 6 7 declare var declare function // 声明全局方法declare class // 声明全局类declare enum // 声明全局枚举类型declare global // 扩展全局变量declare module // 扩展模块
namespace
:“内部模块”现在称做“命名空间”
module X {
相当于现在推荐的写法 namespace X {)
Typescript3.7已发布,新特性有些哪些? Optional chaining (可选链) 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 type AlbumAPIResponse = { title: string artist?: { name: string bio?: string previousAlbums?: string [] } }; declare const album: AlbumAPIResponse;const artistBio = album?.artist?.bio;const maybeArtistBio = album.artist && album.artist.bio;const maybeArtistBioElement = album?.["artist" ]?.["bio" ];const maybeFirstPreviousAlbum = album?.artist?.previousAlbums?.[0 ];const callUpdateMetadata = (metadata: any ) => Promise .resolve(metadata); const updateAlbumMetadata = async (metadata: any , callback?: () => void ) => { await callUpdateMetadata(metadata); callback?.(); };
Nullish Coalescing (空值合并) 空值合并运算符是 || 的替代方法, 如果左边是 null 或 undefined 就返回右边; 看一个例子:
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 interface AppConfiguration { name: string ; items: number ; active: boolean ; } function updateApp (config: Partial<AppConfiguration> ) { config.name = config.name ?? "(no name)" ; config.items = config.items ?? -1 ; config.active = config.active ?? true ; config.name = typeof config.name === "string" ? config.name : "(no name)" ; config.items = typeof config.items === "number" ? config.items : -1 ; config.active = typeof config.active === "boolean" ? config.active : true ; config.name = config.name || "(no name)" ; config.items = config.items || -1 ; config.active = config.active || true ; }
等等…