Category - TypeScript

2022-12-25 18:10:29    0    0    0

Type ‘undefined’ is not assignable to type ‘Function’.

nullundefined 是其它类型(包括 void)的子类型,可以赋值给其它类型(如:数字类型),赋值后的类型会变成 nullundefined
使用第三方/自己的代码声明里没有定义 null | undefined, 可强制转换值的类型

语法

  1. <类型>值

或者(tsx中只能使用这种方式)

  1. as 类型
2022-12-25 17:50:19    0    0    0
2022-12-25 15:00:32    0    0    0
  1. 如果你有module.tsmodule.d.ts在同一个文件夹中(重名),编译器会跳过module.d.ts文件,所以你的声明将不被考虑。重命名d.ts文件或将其移动到另一个文件夹。如果您有合适的模块,这种方法很好,但是如果您想在模块之间共享类型,最好使用import .. from ..
  2. .d.ts文件中有importexport,它就会成为一个模块,并且该模块中的所有内容都必须由使用者随后导入。

声明全局到单独一个文件

  • 创建一个 node_modules/@types/foo/index.d.ts 文件,存放 foo 模块的声明文件。不太建议用这种方案,一般只用作临时测试。
  • 创建一个 types 目录,专门用来管理自己写的声明文件,将 foo 的声明文件放到 types/foo/index.d.ts 中。这种方式需要配置下 tsconfig.json 中的 pathsbaseUrl 字段。

    1. // path/to/project
    2. ├── src
    3. | └── foo
    4. | └── index.ts
    5. ├── types
    6. | └── foo
    7. | └── index.d.ts
    8. └── tsconfig.json
    9. // tsconfig.json
    10. {
    11. "compilerOptions": {
    12. "module": "commonjs",
    13. "baseUrl": "./",
    14. "paths": {
    15. "*": ["types/*"]
    16. }
    17. }
    18. }

声明模块到全局

  • 同上
  • declare
  1. declare namespace 模块名称 { // 模块名称加了引号为外部模块, 不加为作用域
  2. // 从TS2.9开始,我们可以使用import()语法
  3. type User = import('./user').User;
  4. export interface Request {
  5. user: User;
  6. target: User;
  7. friend: User;
  8. }
  9. export class SuperUser implements User {
2022-12-24 20:19:50    0    0    0

定义了一个 EitherOr 的类型来处理这种情况

  1. type FilterOptional<T> = Pick<
  2. T,
  3. Exclude<
  4. {
  5. [K in keyof T]: T extends Record<K, T[K]> ? K : never
  6. }[keyof T],
  7. undefined
  8. >
  9. >
  10. type FilterNotOptional<T> = Pick<
  11. T,
  12. Exclude<
  13. {
  14. [K in keyof T]: T extends Record<K, T[K]> ? never : K
  15. }[keyof T],
  16. undefined
  17. >
  18. >
  19. type PartialEither<T, K extends keyof any> = {
  20. [P in Exclude<keyof FilterOptional<T>, K>]-?: T[P]
  21. } & { [P in Exclude<keyof FilterNotOptional<T>, K>]?: T[P] } & {
  22. [P in Extract<keyof T, K>]?: undefined
  23. }
  24. type Objects = {
  25. [name: string]: any
  26. }
  27. type EitherOr<O extends Objects, L extends string, R extends string> = (
  28. | PartialEither<Pick<O, L | R>, L>
  29. | PartialEither<Pick<O, L | R>, R>
  30. ) &
  31. Omit<O, L | R>

使用例子

  1. // a、b二选一,并且必须传递一个
  2. type RequireOne = EitherOr<
  3. {
  4. a: number;
  5. b: string;
  6. },
  7. 'a',
  8. 'b'
  9. >;
  10. // a、b二选一,或者都不传
  11. type RequireOneOrEmpty = EitherOr<
  12. {
  13. a?: number;
  14. b?: string;
  15. },
  16. 'a',
  17. 'b'
  18. >;

实际应用

  1. interfac
2022-12-23 21:32:49    0    0    0

1. 接口(interface)

1. interface

接口主要用于类型检查,他只是一个结构契约,定义了具有相似的名称和类型的对象结构。除此之外,接口还可以定义方法和事件

An interface is primarily used for type checking; it is simply a structural contract that defines the structure of objects with similar names and types. In addition, interfaces can define methods and events

2. 类型别名(Type Alias)

不同与intetrface只能定义对象类型,type声明任何类型,包括定义基础类型,联合声明或交叉类型

差异点

  1. 定义类型范围
    interface只能定义对象类型,而type声明可以声明任何类型,包括基础类型、联合类型或交叉类型

    1. //基本数据类型
    2. type person = string
    3. //联合类型
    4. interface Dog {
    5. name: string;
    6. }
    7. interface Cat {
    8. age: number;
    9. }
    10. type animal = Dog | Cat
    11. //元组类型
    12. interface Dog {
    13. name: string;
    14. }
    15. interface Cat {
    16. age: number;
    17. }
    18. type animal = [Dog, Cat]
    19. // 交叉类型
    20. type Person = {
    21. name: string
    22. }
    23. type User = Person & { age: number }
    24. // type & interface
    25. interface Person {
    26. name: string
    27. }
    28. type User = {age: number} & Person
  2. 扩展性
    接口可以extends、implements,从而扩展多个接口或类。类型没有扩展功能

    1. // interface extends interface
    2. interface Person {
    3. name: string
    4. }
    5. interface User extends Person {
2019-11-14 15:46:36    4    0    0
## 布尔类型 ``` let isDone: boolean = true // 布尔类型 ``` ## 数字类型(所有数字都是浮点值, 二, 八, 十, 十六进制文字) ``` let decimal: number = 6; // 十进制(常用) let hex: number = 0xf00d; // 十六进制 let binary: number = 0b1010; // 二进制
2019-11-14 15:46:36    3    0    0
## let和var 1. var会声明提前, let不会 2. var可以在一个作用域内重复声明只得到1个, let重复声明会报错 3. var很怪异, let很正常 ## const 1. 常量, 不可直接修改, 如果是个object的话可以通过`.`+属性修改 2. 其它和let一样 ## 解构(es6新特性) ``` let [a, ...b] = [1, 2, 3,
2019-11-14 15:46:36    2    0    0
## 特点 1. 接口好比一个名字, 用来描述一个类或方法里的要求 2. 只要传入的参数有一个满足接口的必要条件的话, 就是被允许的, 参数属性的顺序和检查器检验没关系 例如: ``` interface LabelledValue { label: string; } function printLabel(labelledObj: LabelledValue) { console