天天看点

项目中可以使用的TypeScript优化

构造状态的联合类型

在项目中,难免会遇到一些场景需要定义状态对象,比如想表示一个页面的状态,可能会定义下面这样的状态

const PageState = {
  Loading: 0,
  Normal: 1,
  Error: 2,
};           

复制

 然后我们的数据源可能会使用某个字段来引用它,比如

const pageData = {
    //...
   state:PageState.Loading
}           

复制

 但是我们希望这里的state不能是PageState键值以外的值,所以我们可以构造一个类型来限制赋值,如果PageState的键值相同就很方便,不同的话,我们就需要写一个工具类来获取状态对象所有值构成的联合类型,像这样

type IPageData = {
     //.....
     state:TypeRestfulMethod<typeof PageState> // 0 | 1 | 2
  };

const PageState = {...} as const

type TypeRestfulMethod<T> = T[keyof T];           

复制

 as const 是TS的一种语法,它可以让目标对象在被解析式,不往上方扩展,比如“1”不能被解析为string,它只会被解析为类型“1”,之后我们想在状态对象上添加其他的类型,也不需要遵循相同的值类型了。

推断JSON.Prase序列化之后的类型

在请求接口时,拿回来的数据,一般都是序列化之后的字符串,我们需要先进行反序列化操作,然后再将获取到的数据进行处理,但是,我们在JSON.prase之后,得到的数据并不能推断出具体的类型

项目中可以使用的TypeScript优化

当然这个时候可以使用类型断言,让编译器知道变量的类型

项目中可以使用的TypeScript优化

但我们其实不希望每次使用JSON.parse都手动的去加一个类型断言,毕竟有的时候写类型文件和使用方法的不是同一个人,我们还是希望能写一个接口来统一推断,所以我们可以这样写

type json<T> = string &amp; T

interface JSON {
  parse<T>(text: json<T>, reviver?: (key: any, value: any) => any): T;
  stringify<T>(value: T, replacer?: (key: string, value: any) => any, space?: string | number): json<T>;
  stringify<T>(value: T, replacer?: (number | string)[] | null, space?: string | number): json<T>;
}           

复制

 之后我们就能得到准确的类型推断

type Person = {
  name: string;
  age: number;
};
const role: Person = {
  name: 'jj',
  age: 20,
};
const str: json<Person> = JSON.stringify(role);
const x = JSON.parse(str);           

复制

项目中可以使用的TypeScript优化

为配置文件定义类型

一般情况下,我们的项目都会有多个环境的配置文件,比如.dev,.pro,.release这些,但是里面配置对象的键值都是一样的,像这样。

proConfig = {
   //....
   url:...
   api:...
   corpid:...
}
devConfig = {
   //....
   url:...
   api:...
   corpid:...
}
releaseConfig = {
   //....
   url:...
   api:...
   corpid:...

}           

复制

 但是有时候,我们根据需要去测试环的境配置文件添加一个变量,可能就忘记了去正式和发布环境添加,导致之后打包上线出问题,这个时候我们应该为他们定义一个相同类型,来避免这种情况。

我们可以直接定义一个对应的type,然后赋给三个对象

type IConfig = {
   //....
   url:string
   api:string
   corpid:string
}           

复制

 但是这样有一个问题,就是后续我们如果加新的变量,就需要一直修改类型,显然这很麻烦,所以我们可以根据一个配置文件,来逆向的推导出类型,以dev为例子

const devConfig = {
  url: 'xxx',
  cropid: '123',
};

type IConfigUtil<T extends object> = {
  [P in keyof T]: T[P];
};
type IConfig = IConfigUtil<typeof devConfig>;           

复制

项目中可以使用的TypeScript优化

写在最后

感谢你能看到这里,本文记录了几个关于TS的优化,其实相关的还有很多,后续会陆陆续续的更新,希望对你有所帮助,如果你发现了问题和更好的解决方案,欢迎留言一起讨论