TYPESCRIPT
Arrays 数组
To specify the type of an array like [1, 2, 3]
, you can use the syntax number[]
; this syntax works for any type (e.g. string[]
is an array of strings, and so on). You may also see this written as Array<number>
, which means the same thing. We’ll learn more about the syntax T<U>
when we cover generics.
Note that
[number]
is a different thing; refer to the section on Tuples.
string[]
number[]
Array
Array
Tuple Types 元组类型
A tuple type is another sort of Array
type that knows exactly how many elements it contains, and exactly which types it contains at specific positions.
type StringNumberPair = [string, number];
desctructur tuples 解构元组
We can also destructure tuples using JavaScript’s array destructuring.
function doSomething(stringHash: [string, number]) {
const [inputString, hash] = stringHash;
console.log(inputString);
const inputString: string
console.log(hash);
const hash: number
}
any any类型
TypeScript also has a special type, any
, that you can use whenever you don’t want a particular value to cause typechecking errors.
When a value is of type any
, you can access any properties of it (which will in turn be of type any
), call it like a function, assign it to (or from) a value of any type, or pretty much anything else that’s syntactically legal:
let obj: any = { x: 0 };
// None of the following lines of code will throw compiler errors.
// Using `any` disables all further type checking, and it is assumed
// you know the environment better than TypeScript.
obj.foo();
obj();
obj.bar = 100;
obj = "hello";
const n: number = obj;
union type 联合类型
type ID = number | string;
Interfaces 接口类型
An interface declaration is another way to name an object type:
interface Point {
x: number;
y: number;
}
function printCoord(pt: Point) {
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 100, y: 100 });
Differences Between Type Aliases and Interfaces 类型和接口差异
Type aliases and interfaces are very similar, and in many cases you can choose between them freely. Almost all features of an interface
are available in type
, the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.
Interface |
Type |
---|---|
Extending an interfaceinterface Animal { name: string; } interface Bear extends Animal { honey: boolean; } const bear = getBear(); bear.name; bear.honey; |
Extending a type via intersectionstype Animal = { name: string; } type Bear = Animal & { honey: boolean; } const bear = getBear(); bear.name; bear.honey; |
Adding new fields to an existing interfaceinterface Window { title: string; } interface Window { ts: TypeScriptAPI; } const src = 'const a = "Hello World"'; window.ts.transpileModule(src, {}); |
A type cannot be changed after being createdtype Window = { title: string; } type Window = { ts: TypeScriptAPI; } // Error: Duplicate identifier 'Window'. |
You’ll learn more about these concepts in later chapters, so don’t worry if you don’t understand all of these right away.
Type Assertions类型断言
Sometimes you will have information about the type of a value that TypeScript can’t know about.
For example, if you’re using document.getElementById
, TypeScript only knows that this will return some kind of HTMLElement
, but you might know that your page will always have an HTMLCanvasElement
with a given ID.
In this situation, you can use a type assertion to specify a more specific type:
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;Try
Like a type annotation, type assertions are removed by the compiler and won’t affect the runtime behavior of your code.
You can also use the angle-bracket syntax (except if the code is in a .tsx
file), which is equivalent:
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");
Non-null Assertion Operator (Postfix!
) 非空断言!后缀
TypeScript also has a special syntax for removing null
and undefined
from a type without doing any explicit checking. Writing !
after any expression is effectively a type assertion that the value isn’t null
or undefined
:
function liveDangerously(x?: number | null) {
// No error
console.log(x!.toFixed());
}
变量类型判断 typeof 和Array.isArray
function padLeft(padding: number | string, input: string) {
if (typeof padding === "number") {
return " ".repeat(padding) + input;
}
return padding + input;
}Try
Function Type Expressions
The simplest way to describe a function is with a function type expression. These types are syntactically similar to arrow functions:
function greeter(fn: (a: string) => void) {
fn("Hello, World");
}
function printToConsole(s: string) {
console.log(s);
}
greeter(printToConsole);
The syntax (a: string) => void
means “a function with one parameter, named a
, of type string
, that doesn’t have a return value”. Just like with function declarations, if a parameter type isn’t specified, it’s implicitly any
.
Note that the parameter name is required. The function type
(string) => void
means “a function with a parameter namedstring
of typeany
“!
Of course, we can use a type alias to name a function type:
type GreetFunction = (a: string) => void;
function greeter(fn: GreetFunction) {
// ...
}Try
Thekeyof
type operator
The keyof
operator takes an object type and produces a string or numeric literal union of its keys. The following type P
is the same type as type P = "x" | "y"
:
type Point = { x: number; y: number };
type P = keyof Point;
type P = keyof Point
ReturnType
TypeScript 2.8在lib.d.ts里增加了一些预定义的有条件类型:
Exclude<T, U> -- 从T中剔除可以赋值给U的类型。
Extract<T, U> -- 提取T中可以赋值给U的类型。
NonNullable<T> -- 从T中剔除null和undefined。
ReturnType<T> -- 获取函数返回值类型。
InstanceType<T> -- 获取构造函数类型的实例类型。
This isn’t very useful for basic types, but combined with other type operators, you can use typeof
to conveniently express many patterns. For an example, let’s start by looking at the predefined type ReturnType<T>
. It takes a function type and produces its return type:
type Predicate = (x: unknown) => boolean;
type K = ReturnType<Predicate>;
type K = boolean
Remember that values and types aren’t the same thing. To refer to the type that the value f
has, we use typeof
:
function f() {
return { x: 10, y: 3 };
}
type P = ReturnType<typeof f>;
type P = {
x: number;
y: number;
}