类型声明
类型声明
type
type
关键字能够用于为基础类型typeof
关键字取变量类型,并且赋值给类型变量:
let Some = Math.round(Math.random()) ? "" : 1;
type numOrStr = typeof Some;
let foo: numOrStr;
foo = 123;
foo = "abc";
foo = {}; // Error!
值得一提的是,自typeof
关键字支持动态 import
的类型推导:
const zipUtil: typeof import("./utils/create-zip-file") = await import(
"./utils/create-zip-file"
);
interface
type RestrictedStyleAttribute = "color" | "background-color" | "font-weight";
interface Foo {
// 必要属性
required: Type;
// 可选属性
optional?: Type;
// Hash map,匹配任意字符串类型的键
[key: string]: Type;
// 转化为序列类型
[id: number]: Type;
// 匹配某些固定的键名
[T in RestrictedStyleAttribute]: string;
}
譬如简单的接口定义如下:
interface Story {
title: string;
description?: string;
tags: string[];
}
然后,任意定义包含 title
与 tags
属性的对象都会被当做
let story1: Story = {
title: "Learning TypeScript",
tags: ["typescript", "learning"],
};
接口中同样可以定义函数:
interface StoryExtractor {
extract(url: string): Story;
}
let extractor: StoryExtractor = { extract: (url) => story1 };
或者简写为:
interface StoryExtractor {
(url: string): Story;
}
let extractor: StoryExtractor = (url) => story1;
对于接口的使用,我们将会在下文进行详细的讨论。早期版本中,
// TS Error:
// Interface:
Argument of type '{ x: number; }' is not assignable to parameter of type 'PointInterface'. Property 'y' is missing in type '{ x: number; }'.
// Type alias:
Argument of type '{ x: number; }' is not assignable to parameter of type 'PointType'. Property 'y' is missing in type '{ x: number; }'.
我们可以使用重复定义某个接口,其声明会自动合并;而我们无法使用
interface Box {
height: number;
width: number;
}
interface Box {
scale: number;
}
const box: Box = { height: 5, width: 6, scale: 10 };
类与对象
有时候我们希望将某个类作为参数传递,这个时候的就需要将类声明如下:
type Constructor<T> = new (...args: any[]) => T;
type Constructable = Constructor<{}>;
type Constructor<T = {}> = new (...args: any[]) => T;
lib.d.ts
当你安装
- 它自动包含在
TypeScript 项目的编译上下文中; - 它能让你快速开始书写经过类型检查的
JavaScript 代码。
你可以通过指定 –
"compilerOptions": {
"lib": ["dom", "es6"]
}
-
JavaScript 功能:es5,es6,es2015,es7,es2016,es2017,esnext -
运行环境:dom,dom.iterable,webworker,scripthost
-
ESNext 功能选项:es2015.core,es2015.collection,es2015.generator,es2015.iterable,es2015.promise,es2015.proxy,es2015.reflect,es2015.symbol,es2015.symbol.wellknown,es2016.array.include,es2017.object,es2017.sharedmemory,esnext.asynciterable
修改原始类型
当我们希望使用那些标准的.d.ts
声明文件中。早期的类型声明文件都需要手动地编写与导入,而 DefinitelyTyped 是目前最大的开源类型声明库,其会自动抓取库的类型声明文件,保障我们更加顺滑地使用
// 声明全局变量
declare const require: (moduleId: string) => any;
declare const process: any;
// 声明/扩展命名空间下变量
declare namespace NodeJS {
interface ReadableStream {
destroy: () => {};
}
}
declare global {
interface Window {
__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: Function;
}
interface Math {
seedrandom(seed?: string): void;
}
// Math.seedrandom();
}
declare module "egg" {
// 声明了由插件注入的依赖
interface Application {
knex: Knex;
}
}
如果是某个未包含类型声明的
declare module "rc-queue-anim";
而当我们发布自己的项目时,如果在"declaration": true
,那么执行
{
"typings": "./index.d.ts"
}
而后在
// 类型
export type Reducer<S = any, A extends Action = AnyAction> = (state: S | undefined, action: A) => S;
// 函数
export function combineReducers<S>(reducers: ReducersMapObject<S, any>): Reducer<S>;
export function combineReducers<S, A extends Action = AnyAction>(reducers: ReducersMapObject<S, A>): Reducer<S, A>;
.d.ts
文件同样可以相互引用:
/// <reference path="custom-typings.d.ts" />
DefinitelyTyped
毫无疑问,
可以通过
$ npm install @types/jquery --save-dev
$
。我们也可以像使用模块一样使用它:
import * as $ from "jquery";
// 现在你可以此模块中任意使用$了 :)