Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript - Basic Type (基础类型) #24

Open
wozien opened this issue Oct 27, 2020 · 0 comments
Open

TypeScript - Basic Type (基础类型) #24

wozien opened this issue Oct 27, 2020 · 0 comments

Comments

@wozien
Copy link
Owner

wozien commented Oct 27, 2020

在工作中我们经常用到基础类型,typescript 提供了和 js 一样的基本类型,比如 boolean, string, number, null 等, 并且额外提供了一些有用的辅助类型,比如枚举 enum

typescript中, 类型注解用 变量名: 类型 方式表示。

Boolean

布尔类型是最简单的类型, 取值为 true/false 。 和js一样, 都用 boolean 表示

let isDone: boolean = false;

Number

数字类型用 number 表示, 大数字用 bigint 表示。 另外可以用 0x, 0b 来表示十六和二进制。

let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
let big: bigint = 100n;

String

字符串可以用双引号和单引号,类型为 string

let color: string = "blue";
color = "red";

可以使用类似ES6的模版字符串

let fullName: string = `Bob Bobbington`;
let age: number = 37;
let sentence: string = `Hello, my name is ${fullName}.

I'll be ${age + 1} years old next month.`;

Array

数组类型有两种方式表示, 第一种是数组元素类型紧跟 [] 表示

let list: number[] = [1, 2, 3];

第二种方式是用数组泛型的方式 Array<elemType>

let list: Array<number> = [1, 2, 3];

Tuple

当我们需要表示固定数量的不同类型元素的数组时候,就需要用到元组:

// Declare a tuple type
let x: [string, number];
// Initialize it
x = ["hello", 10]; // OK
// Initialize it incorrectly
x = [10, "hello"]; // Error

当通过访问固定元素时,ts 会自动推断其类型:

// OK
console.log(x[0].substring(1));

console.log(x[1].substring(1)); //Error

访问索引外的元素和赋值也会报错:

console.log(x[5].toString()); // Error
x[3] = "world"; // Error

Enum

枚举类型是提供一系列的变量来表示数据集的类型, 用 enum 表示:

enum Color {
  Red,
  Green,
  Blue,
}
let c: Color = Color.Green; // 0

枚举元素默认是从0开始,可以通过设置改变默认值:

enum Color {
  Red = 1,
  Green,
  Blue,
}
let c: Color = Color.Green;

同样地,可以手动设置枚举元素的所有值:

enum Color {
  Red = 1,
  Green = 2,
  Blue = 4,
}
let c: Color = Color.Green;

可以用过数值获取对应的枚举名:

enum Color {
  Red = 1,
  Green,
  Blue,
}
let colorName: string = Color[2];
console.log(colorName); // 'Green'

Unknown

当我们想要表述一个不能确定的类型或者有意接受API返回的所有可能的类型,这时可以用 unknown 类型表示:

let notSure: unknown = 4;
notSure = "maybe a string instead";

// OK, definitely a boolean
notSure = false;

不能赋值给具体类型的变量:

let maybe: unknown

// ok
let maybe1: unknown = maybe
let maybe2: any = maybe1

// error
const name: string = maybe

可以通过比较、typeof 等类型守卫方式来解决:

if (maybe === true) {
  // TypeScript knows that maybe is a boolean now
  const aBoolean: boolean = maybe;
  // So, it cannot be a string
  const aString: string = maybe;
// Type 'boolean' is not assignable to type 'string'.
}

if (typeof maybe === "string") {
  // TypeScript knows that maybe is a string
  const aString: string = maybe;
  // So, it cannot be a boolean
  const aBoolean: boolean = maybe;
// Type 'string' is not assignable to type 'boolean'.
}

Any

在某些情况,并非所有类型信息都是可用的否则他的类型声明将会耗费很大精力。这在不用typescript 编写的代码或者第三方库经常发生。所以,我们选择退出类型检查,可以用 any 表示这些值:

declare function getValue(key: string): any;
// OK, return value of 'getValue' is not checked
const str: string = getValue("myString");

unknown 类型不同,any 类型的变量可以访问任何属性和函数,尽管他们可能不存在,因为 typescrpt 不会检查:

let looselyTyped: any = 4;
// OK, ifItExists might exist at runtime
looselyTyped.ifItExists();
// OK, toFixed exists (but the compiler doesn't check)
looselyTyped.toFixed();

let strictlyTyped: unknown = 4;
strictlyTyped.toFixed(); // Error, Object is of type 'unknown'.

any 类型会在对象访问中传递:

let looselyTyped: any = {};
let d = looselyTyped.a.b.c.d;
//  ^ = let d: any

使用any类型会让我们丢失typescript特性--类型安全,我们应该尽量避免使用

Void

void 有点和 any 类型互斥, 表示不是任何类型。经常会在函数没有返回值时使用:

function warnUser(): void {
  console.log("This is my warning message");
}

定义一个变量为void 类型是无用的,因为你只能用nullundefined 类型进行赋值(需要打开 --strictNullChecks 配置):

let unusable: void = undefined;
// OK if `--strictNullChecks` is not given
unusable = null

Null and Undefined

nullundefined 类型的值其实用处也不大, 在开启 --strictNullChecks的前提下,只能赋值给unknownany 和他们各自的类型, 其中 undefined 赋值给 void 是个例外。否则,它们可以赋值给任何类型:

// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;

let maybe: unknown = undefined

// strictNullChecks = false
let num:number = undefined

Never

never 类型表示一个总会抛出异常的函数或者死循环的函数,因为它们永远不可能返回值。例外, never 类型不能赋值给任何类型, 其他任何类型也不能赋值给它:

// Function returning never must not have a reachable end point
function error(message: string): never {
  throw new Error(message);
}

// Inferred return type is never
function fail() {
  return error("Something failed");
}

// Function returning never must not have a reachable end point
function infiniteLoop(): never {
  while (true) {}
}

Object

object 类型表示所有非原始类型, 即不是 boolean, number, string, bigint, symbol, nullundefined, 但是一般情况不会用到:

declare function create(o: object | null): void;

// OK
create({ prop: 0 });
create(null);

create(42);
// Argument of type '42' is not assignable to parameter of type 'object | null'.
create("string");
// Argument of type '"string"' is not assignable to parameter of type 'object | null'.
create(false);
// Argument of type 'false' is not assignable to parameter of type 'object | null'.
create(undefined);
// Argument of type 'undefined' is not assignable to parameter of type 'object | null'.

Type assertions

在某些情况,你知道某个值的类型比当前类型更加具体时, 你需要用到类型断言。 类型断言时一种告诉编译器“trust me, I know what I’m doing.”的感觉, 也类似于其他静态语言的类型转换,但是它不执行任何数据检查和转换。另外它只是在编译阶段有效,对运行是没影响的。

类型断言有两种方式,第一钟是 as 语法:

let value: unknown = 'hello'

let len: number = (value as string).length

另一种使用 angle-bracket 语法:

let value: unknown = 'hello'

let len: number = (<string>value).length

其中第一方式优于第二种方式, 并且在JSX使用时,只有用 as 语法

不应该用String, Number等作为类型注解, 而是用小写的方式,尽管它们效果相同

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant