包含最重要基礎、泛型、方法、class 等 TypeScript 強類型編程語言語法的快速參考備忘單。初學者的完整快速參考
TypeScript 是具有類型語法的 JavaScript。Interface 是為了匹配它們的運行時行為而構建的。
any, void,
boolean, string, number,
undefined, null,
unknown, never,
bigint, symbol
Date, Error,
Array, Map, Set,
Regexp, Promise
Object:
{ field: string }
Function:
(arg: number) => string
Arrays:
string[] or Array<string>
Tuple:
[string, number]
Object, String, Number, Boolean
/** 可選擇從現有接口或類型(Response, HTTPAble)中獲取屬性 */
interface JSONResponse extends Response, HTTPAble {
version: number;
// ?? 附加在編輯器中顯示的 JSDoc 注釋
/** In bytes */
payloadSize: number;
// ?? 此屬性可能不在對象上
outOfStock?: boolean;
// ?? 這是描述作為函數的屬性的兩種方法
update: (retryTimes: number) => void;
update(retryTimes: number): void;
// ?? 你可以通過 () 調用這個對象 -(JS中的函數是可以調用的對象)
(): JSONResponse
// ?? 您可以在此 Interface 描述的對象上使用 new
new(s: string): JSONResponse;
// ?? 任何未描述的屬性都假定存在,并且所有屬性必須是數字
[key: string]: number;
// ?? 告訴 TypeScript 一個屬性不能被改變
readonly body: string;
}
聲明一個可以在你的 Interface 中改變的類型
interface APICall<Response> {
data: Response
}
const api: APICall<ArtworkCall> = ...
api.data // Artwork
您可以通過 extends
關鍵字限制泛型參數接受的類型。
interface APICall<Response extends { status: number }> {
data: Response
}
const api: APICall<ArtworkCall> = ...
api.data.status
interface Expect {
(matcher: boolean): string
(matcher: string): boolean;
}
一個可調用 Interface 可以對不同的參數集有多個定義。
interface Syncable {
sync(): void
}
class Account implements Syncable { ... }
您可以通過實現確保類 class 符合 Interface。
對象可以有自定義的 getter
或 setter
。
interface Ruler {
get size(): number
set size(value: number | string);
}
用法
const r: Ruler = ...
r.size = 12
r.size = "36"
interface APICall {
data: Response
}
interface APICall {
error?: Error
}
Interface 被合并,多個聲明將向類型定義添加新字段。
就像您如何在不同范圍內創建具有相同名稱的變量一樣,type 具有相似的語義。
TypeScript 包含許多全局類型,它們將幫助您在類型系統中完成常見任務。檢查他們的網站。
type SanitizedInput = string;
type MissingNo = 404;
主要用于文檔
type Location = {
x: number;
y: number;
};
type Size = "small" | "medium" | "large"
描述許多選項中的一個類型,例如已知字符串的列表。
type Location = { x: number }
& { y: number }
// { x: number, y: number }
一種合并/擴展類型的方法
const data = { ... }
type Data = typeof data
通過 typeof 運算符重用來自現有 JavaScript 運行時值的類型。
const createFixtures = () => { ... }
type Fixtures = ReturnType<typeof createFixtures>
function test(fixture: Fixtures) {}
將函數的返回值重新用作類型。
const data: import("./data").data
這些功能非常適合構建庫、描述現有的 JavaScript 代碼,您可能會發現在大多數 TypeScript 應用程序中很少使用它們。
type JSONResponse = {
version: number; // 字段
/** In bytes */ // 附加文檔
payloadSize: number;
outOfStock?: boolean; // 可選的
update: (retryTimes: number) => void; // 箭頭函數字段
update(retryTimes: number): void; // 函數
(): JSONResponse // 類型是可調用的
[key: string]: number; // 接受任何索引
new (s: string): JSONResponse; // new 對象
readonly body: string; // 只讀屬性
}
用于節省空間的 Terser,請參閱 Interface 備忘清單了解更多信息,除了“static”匹配之外的所有內容。
type Artist = {
name: string, bio: string
}
type Subscriber<Type> = {
[Property in keyof Type]:
(newValue: Type[Property]) => void
}
type ArtistSub = Subscriber<Artist>
// { name: (nv: string) =>
// void, bio: (nv: string) => void }
類似于類型系統的映射語句,允許輸入類型更改新類型的結構。
type SupportedLangs = "en" | "pt" | "zh";
type FooterLocaleIDs = "header" | "footer";
type AllLocaleIDs = `${SupportedLangs}_${FooterLocaleIDs}_id`;
// "en_header_id" | "en_footer_id"
// | "pt_header_id" | "pt_footer_id"
// | "zh_header_id" | "zh_footer_id"
type HasFourLegs<Animal> = Animal extends { legs: 4 } ? Animal : never
type Animals = Bird | Dog | Ant | Wolf;
type FourLegs = HasFourLegs<Animals>
// Dog | Wolf
在類型系統中充當“if 語句”。 通過泛型創建,然后通常用于減少類型聯合中的選項數量。
const input = getUserInput()
input // string | number
if (typeof input === 'string') {
input // string
}
const input = getUserInput()
input // string | { error: ... }
if ('error' in input) {
input // { error: ... }
}
const input = getUserInput()
input // number | number[]
if (input instanceof Array) {
input // number[]
}
const input = getUserInput()
input // number | number[]
if (Array.isArray(input)) {
input // number[]
}
const data1 = {
name: "Zagreus"
}
// typeof data1 = {
// name: string
// }
?? 使用 as const
縮小類型 ??
const data2 = {
name: "Zagreus"
} as const
// typeof data1 = {
// name: 'Zagreus'
// }
跟蹤相關變量
const response = getResponse()
const isSuccessResponse =
res instanceof SuccessResponse
if (isSuccessResponse) {
res.data // SuccessResponse
}
重新分配更新類型
let data: string | number = ...
data // string | number
data = "Hello"
data // string
CFA 幾乎總是采用聯合,并根據代碼中的邏輯減少聯合內的類型數量。
大多數時候 CFA 在自然 JavaScript 布爾邏輯中工作,但是有一些方法可以定義您自己的函數,這些函數會影響 TypeScript 如何縮小類型。
const input = getUserInput()
input // string | number
const inputLength =
(typeof input === "string" && input.length)
|| input
// input: string
在進行布爾運算時,縮窄也發生在與代碼相同的行上
type Responses =
| { status: 200, data: any }
| { status: 301, to: string }
| { status: 400, error: Error }
const response = getResponse()
response // Responses
switch(response.status) {
case 200: return response.data
case 301: return redirect(response.to)
case 400: return response.error
}
描述影響當前范圍的 CFA 更改的函數,因為它拋出而不是返回 false。
function assertResponse(obj: any): asserts obj is SuccessResponse {
if (!(obj instanceof SuccessResponse)) {
throw new Error('Not a success!')
}
}
const res = getResponse():
res // SuccessResponse | ErrorResponse
// 斷言函數改變當前作用域或拋出
assertResponse(res)
res // SuccessResponse
interface A {
x: number;
}
interface B {
y: string;
}
function doStuff(q: A | B) {
if ('x' in q) {
// q: A
} else {
// q: B
}
}
操作符可以安全的檢查一個對象上是否存在一個屬性,它通常也被作為類型保護使用
class ABC { ... }
const abc = new ABC()
新 ABC 的參數來自構造函數。
前綴 private 是一個僅類型的添加,在運行時沒有任何影響。 在以下情況下,類之外的代碼可以進入項目:
class Bag {
private item: any
}
Vs #private 是運行時私有的,并且在 JavaScript 引擎內部強制執行,它只能在類內部訪問:
class Bag { #item: any }
函數內部‘this’的值取決于函數的調用方式。 不能保證始終是您可能在其他語言中使用的類實例。
您可以使用“此參數”、使用綁定功能或箭頭功能來解決問題。
一個類既可以用作類型也可以用作值。
const a:Bag = new Bag()
所以,小心不要這樣做:
class C implements Bag {}
// 確保類符合一組接口或類型 ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈?┈┈╮
// 子類這個類 ┈┈┈┈┈┈┈┈↘ ┈┈┈┈┈┈┈┈┈┈┈┈┈┴┈┈┈┈┈┈┈
class User extends Account implements Updatable, Serializable {
id: string; // 一個字段
displayName?: boolean; // 可選字段
name!: string; // '相信我,它在哪里'字段
#attributes: Map<any, any>; // 私人字段
roles = ["user"]; // 具有默認值的字段
readonly createdAt = new Date() // 具有默認值的只讀字段
// ?? 代碼調用“new”
constructor(id: string, email: string) {
super(id);
// ?? 在 `strict: true` 中,會根據字段檢查此代碼以確保其設置正確
this.email = email;
// ....
};
// ?? 描述類方法(和箭頭函數字段)的方式
setName(name: string) { this.name = name }
verifyName = (name: string) => { /* ... */ }
// ?? 具有 2 個重載定義的函數
sync(): Promise<{ ... }>
sync(cb: ((result: string) => void)): void
sync(cb?: ((result: string) => void)): void | Promise<{ ... }> {}
// ?? Getters 和 setters
get accountID() { }
set accountID(value: string) { }
// ?? 私有訪問只是對這個類,受保護的允許子類。 僅用于類型檢查,public 是默認值。
private makeRequest() { ... }
protected handleRequest() { ... }
// ?? 靜態字段/方法
static #userCount = 0;
static registerUser(user: User) { ... }
// ?? 用于設置靜態變量的靜態塊。 ‘this’指的是靜態類
static { this.#userCount = -1 }
}
聲明一個可以在你的類方法中改變的類型。
class Box<Type> {
contents: Type
constructor(value: Type) {
this.contents = value;
}
}
const stringBox = new Box("a package")
這些功能是 TypeScript 特定的語言擴展,可能永遠無法使用當前語法進入 JavaScript。
class Location {
constructor(public x: number, public y: number) {}
}
const loc = new Location(20, 40);
loc.x // 20
loc.y // 40
TypeScript 特定于類的擴展,可自動將實例字段設置為輸入參數。
abstract class Animal {
abstract getName(): string;
printName() {
console.log("Hello, " + this.getName());
}
}
class Dog extends Animal { getName(): { ... } }
一個類可以被聲明為不可實現,但可以在類型系統中被子類化。 class 成員也可以。
import { Syncable, triggersSync, preferCache, required } from "mylib"
@Syncable
class User {
@triggersSync()
save() { ... }
@preferCache(false)
get displayName() { ... }
update(@required info: Partial<User>) { ... }
}
您可以在類、類方法、訪問器、屬性和方法參數上使用裝飾器。
class MyClass {
// 最好將索引數據存儲在另一個地方
// 而不是類實例本身。
[s: string]:
boolean | ((s: string) => boolean);
check(s: string) {
return this[s] as boolean;
}
}
類可以聲明索引簽名,與其他對象類型的索引簽名相同。
type A = Awaited<Promise<string>>;
// type A = string
type B = Awaited<Promise<Promise<number>>>;
// type B = number
type C = Awaited<boolean|Promise<number>>;
// type C = number | boolean
這種類型旨在模擬異步函數中的 await 或 Promises 上的 .then() 方法等操作 - 特別是它們遞歸解包 Promises 的方式。
interface Props {
a?: number;
b?: string;
}
const obj: Props = { a: 5 };
const obj2: Required<Props> = { a: 5 };
// ? 類型“{ a: number;”中缺少屬性“b” }'
// 但在 'Required<Props>' 類型中是必需的。
使 Type 中的所有屬性成為必需
interface Todo {
title: string;
}
const todo: Readonly<Todo> = {
title: "Delete inactive users",
};
todo.title = "Hello";
// ? 無法分配給“title”,因為它是只讀屬性。
function freeze<Type>(obj: Type)
: Readonly<Type>;
將 Type 中的所有屬性設為只讀
interface Todo {
title: string;
description: string;
}
function updateTodo(
todo: Todo,
fieldsToUpdate: Partial<Todo>
) {
return { ...todo, ...fieldsToUpdate };
}
const todo1 = {
title: "organize desk",
description: "clear clutter",
};
const todo2 = updateTodo(todo1, {
description: "throw out trash",
});
將 Type
中的所有屬性設為可選
interface CatInfo {
age: number;
breed: string;
}
type CatName = "miffy" | "boris";
const cats: Record<CatName, CatInfo> = {
miffy: {age:10, breed: "Persian" },
boris: {age:5, breed: "Maine Coon" },
};
cats.boris;
// ?? const cats: Record<CatName, CatInfo>
構造一個具有一組 Keys 類型的屬性 Type 的類型
interface Todo {
name: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<
Todo, "name" | "load"
>;
const todo: TodoPreview = {
name: "Clean room",
load: false,
};
todo;
// ?? const todo: TodoPreview
從 Type 中選擇一組其鍵在并集 Keys 中的屬性
type T0 = Exclude<"a" | "b" | "c", "a">;
// ?? type T0 = "b" | "c"
type T1 = Exclude<"a"|"b"|"c", "a" | "b">;
// ?? type T1 = "c"
type T2 = Exclude<string | number |
(() => void), Function>;
// ?? type T2 = string | number
從 UnionType
中排除那些可分配給 ExcludedMembers
的類型
type T0 = Extract<
"a" | "b" | "c", "a" | "f"
>;
// type T0 = "a"
type T1 = Extract<
string | number | (() => void),
Function
>;
// type T1 = () => void
通過從 Type 中提取所有可分配給 Union 的聯合成員來構造一個類型。
type T0 = NonNullable<
string | number | undefined
>;
// type T0 = string | number
type T1 = NonNullable<
string[] | null | undefined
>;
// type T1 = string[]
通過從 Type 中排除 null 和 undefined 來構造一個類型。
interface Todo {
name: string;
completed: boolean;
createdAt: number;
}
type TodoPreview = Omit<Todo, "name">;
const todo: TodoPreview = {
completed: false,
createdAt: 1615544252770,
};
todo;
// ?? const todo: TodoPreview
構造一個具有 Type 屬性的類型,但類型 Keys 中的屬性除外。
declare function f1(
arg: { a: number; b: string }
): void;
type T0 = Parameters<() => string>;
// type T0 = []
type T1 = Parameters<(s: string) => void>;
// type T1 = [s: string]
type T2 = Parameters<<T>(arg: T) => T>;
// type T2 = [arg: unknown]
type T3 = Parameters<typeof f1>;
// type T3 = [arg: {
// a: number;
// b: string;
// }]
type T4 = Parameters<any>;
// type T4 = unknown[]
type T5 = Parameters<never>;
// type T5 = never
從函數類型 Type 的參數中使用的類型構造元組類型。
type T0 = ConstructorParameters<
ErrorConstructor
>;
// type T0 = [message?: string]
type T1 = ConstructorParameters<
FunctionConstructor
>;
// type T1 = string[]
type T2 = ConstructorParameters<
RegExpConstructor
>;
// type T2 = [
// pattern: string | RegExp,
// flags?: string
// ]
type T3 = ConstructorParameters<any>;
// type T3 = unknown[]
從構造函數類型的類型構造元組或數組類型。它產生一個包含所有參數類型的元組類型(如果 Type 不是函數,則類型 never )。
type Greeting = "Hello, world"
type ShoutyGreeting = Uppercase<Greeting>
// type ShoutyGreeting = "HELLO, WORLD"
type ASCIICacheKey<Str extends string> = `ID-${Uppercase<Str>}`
type MainID = ASCIICacheKey<"my_app">
// type MainID = "ID-MY_APP"
將字符串中的每個字符轉換為大寫版本。
type Greeting = "Hello, world"
type QuietGreeting = Lowercase<Greeting>
// type QuietGreeting = "hello, world"
type ASCIICacheKey<Str extends string> = `id-${Lowercase<Str>}`
type MainID = ASCIICacheKey<"MY_APP">
// type MainID = "id-my_app"
將字符串中的每個字符轉換為等效的小寫字母。
type LowercaseGreeting = "hello, world";
type Greeting = Capitalize<LowercaseGreeting>;
// type Greeting = "Hello, world"
將字符串中的第一個字符轉換為等效的大寫字母。
type UppercaseGreeting = "HELLO WORLD";
type UncomfortableGreeting = Uncapitalize<UppercaseGreeting>;
// type UncomfortableGreeting = "hELLO WORLD"
將字符串中的第一個字符轉換為等效的小寫字母。
declare function f1(): {
a: number; b: string
};
type T0 = ReturnType<() => string>;
// type T0 = string
type T1 = ReturnType<(s: string) => void>;
// type T1 = void
type T2 = ReturnType<<T>() => T>;
// type T2 = unknown
type T3 = ReturnType<<
T extends U, U extends number[]
>() => T>;
// type T3 = number[]
type T4 = ReturnType<typeof f1>;
// type T4 = {
// a: number;
// b: string;
// }
type T5 = ReturnType<any>;
// type T5 = any
type T6 = ReturnType<never>;
// type T6 = never
構造一個由函數 Type 的返回類型組成的類型。
type ObjectDescriptor<D, M> = {
data?: D;
// 方法中“this”的類型是 D & M
methods?: M & ThisType<D & M>;
};
function makeObject<D, M>(
desc: ObjectDescriptor<D, M>
): D & M {
let data: object = desc.data || {};
let methods: object = desc.methods || {};
return { ...data, ...methods } as D & M;
}
let obj = makeObject({
data: { x: 0, y: 0 },
methods: {
moveBy(dx: number, dy: number) {
this.x += dx; // Strongly typed this
this.y += dy; // Strongly typed this
},
},
});
obj.x = 10;
obj.y = 20;
obj.moveBy(5, 5);
此實用程序不返回轉換后的類型。 相反,它用作上下文 this 類型的標記。 請注意,必須啟用 標志才能使用此實用程序。
class C {
x = 0;
y = 0;
}
type T0 = InstanceType<typeof C>;
// type T0 = C
type T1 = InstanceType<any>;
// type T1 = any
type T2 = InstanceType<never>;
// type T2 = never
構造一個由 Type 中構造函數的實例類型組成的類型。
function toHex(this: Number) {
return this.toString(16);
}
function numberToString(
n: ThisParameterType<typeof toHex>
) {
return toHex.apply(n);
}
提取函數類型的 this
參數的類型,如果函數類型沒有 this
參數,則為未知。
function toHex(this: Number) {
return this.toString(16);
}
const fiveToHex
: OmitThisParameter<typeof toHex>
= toHex.bind(5);
console.log(fiveToHex());
從 Type 中移除 this 參數。 如果 Type 沒有顯式聲明此參數,則結果只是 Type。 否則,從 Type 創建一個不帶此參數的新函數類型。 泛型被刪除,只有最后一個重載簽名被傳播到新的函數類型中。
JSX 規范是對 ECMAScript 的類似 XML 的語法擴展。
.tsx
擴展名命名您的文件jsx
選項.tsx
文件中使用尖括號類型斷言。const foo = <foo>bar;
// ? 不允許在 .tsx ?? 文件中使用尖括號類型斷言。
const foo = bar as foo;
as
運算符在 .ts
和 .tsx
文件中都可用,并且在行為上與尖括號類型斷言樣式相同。
import MyComponent from "./myComponent";
<MyComponent />; // ok
<SomeOtherComponent />; // ? error
基于值的元素只是由范圍內的標識符查找。
declare namespace JSX {
interface IntrinsicElements {
foo: any;
}
}
<foo />; // ok
<bar />; // error
<bar /> 沒有在 JSX.IntrinsicElements 上指定。
declare namespace JSX {
interface IntrinsicElements {
[elemName: string]: any;
}
}
interface FooProp {
name: string;
X: number;
Y: number;
}
declare function AnotherComponent(prop: { name: string });
function ComponentFoo(prop: FooProp) {
return <AnotherComponent name={prop.name} />;
}
const Button = (prop: { value: string }, context: { color: string }) => (
<button />
);
該組件被定義為一個 JavaScript 函數,其第一個參數是一個 props 對象。 TS 強制它的返回類型必須可分配給 JSX.Element。
interface CeProps {
children: JSX.Element[] | JSX.Element;
}
interface HomeProps extends CeProps {
home: JSX.Element;
}
interface SideProps extends CeProps {
side: JSX.Element | string;
}
function Dog(prop:HomeProps): JSX.Element;
function Dog(prop:SideProps): JSX.Element;
function Dog(prop:CeProps): JSX.Element {
// ...
}
interface MenuProps extends React.LiHTMLAttributes<HTMLUListElement> { ... }
const InternalMenu = (props: MenuProps, ref?: React.ForwardedRef<HTMLUListElement>) => (
<ul {...props} ref={ref} />
);
type MenuComponent = React.FC<React.PropsWithRef<MenuProps>> & {
Item: typeof MenuItem; // MenuItem 函數組件
SubMenu: typeof SubMenu; // SubMenu 函數組件
};
const Menu: MenuComponent = React.forwardRef<HTMLUListElement>(
InternalMenu
) as unknown as MenuComponent;
Menu.Item = MenuItem;
Menu.SubMenu = SubMenu;
<Menu.Item /> // ? ok
<Menu.SubMenu /> // ? ok
declare namespace JSX {
interface ElementClass {
render: any;
}
}
class MyComponent {
render() {}
}
function MyFactoryFunction() {
return { render: () => {} };
}
<MyComponent />; // ? 有效類組件
<MyFactoryFunction />; // ? 有效函數組件
元素實例類型必須可以分配給 JSX.ElementClass
,否則將導致錯誤。
class NotAValidComponent {}
function NotAValidFactoryFunction() {
return {};
}
<NotAValidComponent />; // ? error
<NotAValidFactoryFunction />; // ? error
默認情況下,JSX.ElementClass
是 {},但可以對其進行擴展,以將 JSX
的使用限制為僅限于符合適當接口的類型。
type Props = {
header: React.ReactNode;
body: React.ReactNode;
};
class MyComponent extends React.Component<Props, {}> {
render() {
return (
<div>
{this.props.header}
{this.props.body}
</div>
);
}
}
<MyComponent header={<h1>Header</h1>} body={<i>body</i>} />
// 一個泛型組件
type SelectProps<T> = { items: T[] };
class Select<T> extends React.Component<SelectProps<T>, any> {}
// 使用
const Form = () => <Select<string> items={['a', 'b']} />;
import { FC, ForwardedRef, forwardRef, PropsWithRef } from "react";
function InternalProgress(props: ProgressProps, ref?: ForwardedRef<HTMLDivElement>) {
return (
<div {...props} ref={ref}>
{props.children}
</div>
)
}
export interface ProgressProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {}
export const Progress: FC<PropsWithRef<ProgressProps>> = forwardRef<HTMLDivElement>(InternalProgress)
type Capitalize<T extends string> = T extends `${infer U}${infer V}`
? `${Uppercase<U>}${V}`
: T
type capitalized = Capitalize<"hello world"> // Hello World
也可以在 infer 中使用條件約束(extends
)
type SomeBigInt = "100" extends `${infer U extends bigint}` ? U : never;
// 100n
interface Point {
x: number;
y: number;
}
// type keys = "x" | "y"
type keys = keyof Point;
interface NumberOrString {
[index: string]: string | number;
length: number;
name: string;
}
type Point = { x: number; y: number; }
type Data = Point[];
// Data 是個數組,提取里面的元素類型
type PointDetail = Data[number];
// type PointDetail = { x: number; y: number; }
const point = [3, 4] as const
// type 'readonly [3, 4]'
satisfies
允許將驗證表達式的類型與某種類型匹配,而無需更改該表達式的結果類型。
type Colors = 'red' | 'green' | 'blue';
type RGB = [
red: number,
green: number,
blue: number
];
type Palette = Record<Colors, string | RGB>
const palette: Palette = {
red: [255, 0, 0],
green: '#00ff00',
blue: [0, 0, 255],
};
// 通常的方式會推導出 redComponent 為
// => string | number | undefined
const redComponent = palette.red.at(0);
const palette = {
red: [255, 0, 0],
green: '#00ff00',
blue: [0, 0, 255],
} satisfies Record<Colors, string | RGB>
// undefined | number
const redComponent = palette.red.at(0)
不使用的情況下:
const errorMap: Map<string, Error> = new Map()
// 或者使用 type 定義別名
type ErrorMapType = Map<string, Error>
使用泛型實例化表達式:
const ErrorMap = Map<string, Error>
const errorMap = new ErrorMap()
function makeBox<T>(value: T) {
return { value };
}
不使用:
function makeHammerBox(hammer: Hammer) {
return makeBox(hammer);
}
// or...
const makeWrenchBox: (wrench: Wrench) => Box<Wrench> = makeBox;
使用:
const makeStringBox = makeBox<string>;
makeStringBox(42);
declare global {
interface String {
fancyFormat(opts: FancyOption): string;
}
}
export interface FancyOption {
fancinessLevel: number;
}
例如,當您想使用擴展另一個庫的 JavaScript 代碼時
import { greeter } from "super-greeter";
// 普通歡迎 API
greeter(2);
greeter("Hello world");
// 現在我們在運行時用一個新函數擴展對象
import "hyper-super-greeter";
greeter.hyperGreet();
"super-greeter
" 的定義:
/* 此示例說明如何為您的函數設置多個重載 */
export interface GreeterFunction {
(name: string): void
(time: number): void
}
/* 此示例顯示如何導出接口指定的函數 */
export const greeter: GreeterFunction;
我們可以像下面這樣擴展現有模塊:
/* 導入這個模塊添加到的模塊 */
import { greeter } from "super-greeter";
/* 聲明與上面導入的模塊相同的模塊,然后我們擴展 greeter 函數的現有聲明 */
export module "super-greeter" {
export interface GreeterFunction {
/** Greets even better! */
hyperGreet(): void;
}
}
全局庫可能如下所示:
function createGreeting(s) {
return "Hello, " + s;
}
或者像這樣:
window.createGreeting = function (s) {
return "Hello, " + s;
};
/* 可以作為 myLib(3) 此處包含這些調用簽名 */
declare function myLib(a: string): string;
declare function myLib(a: number): number;
/* 如果你希望這個庫的名稱是一個有效的類型名稱,你可以在這里這樣做例如,這允許我們寫 'var x: myLib'; 確保這確實有意義! 如果沒有,只需刪除此聲明并在下面的命名空間內添加類型 */
interface myLib {
name: string;
length: number;
extras?: string[];
}
/* 如果您的庫在全局變量上公開了屬性,請將它們放在此處。 您還應該在此處放置類型(接口和類型別名) */
declare namespace myLib {
// 我們可以寫 'myLib.timeout = 50;'
let timeout: number;
// 我們可以訪問 'myLib.version',但不能更改它
const version: string;
// 我們可以通過 'let c = new myLib.Cat(42)' 創建一些類或參考例如 '函數 f(c: myLib.Cat) { ... }
class Cat {
constructor(n: number);
// 我們可以從 'Cat' 實例中讀取 'c.age'
readonly age: number;
// 我們可以從 'Cat' 實例調用 'c.purr()'
purr(): void;
}
// 我們可以將變量聲明為
// 'var s: myLib.CatSettings = { weight: 5, name: "Maru" };'
interface CatSettings {
weight: number;
name: string;
tailLength?: number;
}
// 我們可以寫 'const v: myLib.VetID = 42;'
// 或 'const v: myLib.VetID = "bob";'
type VetID = string | number;
// 我們可以調用 'myLib.checkCat(c)' 或 'myLib.checkCat(c, v);'
function checkCat(c: Cat, s?: VetID);
}
import greeter from "super-greeter";
greeter(2);
greeter("Hello world");
要處理通過 UMD
和模塊導入:
/* 如果此模塊是一個 UMD 模塊,在模塊加載器環境之外加載時公開全局變量“myFuncLib”,請在此處聲明該全局變量。 否則,刪除此聲明 */
export as namespace myFuncLib;
/* 此聲明指定該函數是從文件中導出的對象 */
export = Greeter;
/* 此示例說明如何為您的函數設置多個重載 */
declare function Greeter(name: string): Greeter.NamedReturnType;
declare function Greeter(length: number): Greeter.LengthReturnType;
如果你也想從你的模塊中公開類型,你可以把它們放在這個塊中。 通常你會想要描述函數返回類型的形狀; 如本例所示,應在此處聲明該類型,請注意,如果您決定包含此命名空間,則模塊可能會被錯誤地導入為命名空間對象,除非 --esModuleInterop
已打開: import * as x from '[~THE MODULE~]';
錯誤的!不要這樣做!
declare namespace Greeter {
export interface LengthReturnType {
width: number;
height: number;
}
export interface NamedReturnType {
firstName: string;
lastName: string;
}
/**
* 如果模塊也有屬性,在這里聲明它們。 例如,這個聲明說這個代碼是合法的:
* import f = require('super-greeter');
* console.log(f.defaultName);
*/
export const defaultName: string;
export let defaultLength: number;
}
例如,當您想要使用如下所示的 JavaScript
代碼時:
const Greeter = require("super-greeter");
const greeter = new Greeter();
greeter.greet();
要處理通過 UMD
和模塊導入:
export as namespace "super-greeter";
/* 此聲明指定類構造函數是從文件中導出的對象 */
export = Greeter;
/* 在此類中編寫模塊的方法和屬性 */
declare class Greeter {
constructor(customGreeting?: string);
greet: void;
myMethod(opts: MyClass.MyClassMethodOptions): number;
}
如果你也想從你的模塊中公開類型,你可以把它們放在這個塊中,如果您決定包含此命名空間,則模塊可能會被錯誤地導入為命名空間對象,除非 --esModuleInterop 已打開:
import * as x from '[~THE MODULE~]';
錯誤的! 不要這樣做!
declare namespace MyClass {
export interface MyClassMethodOptions {
width?: number;
height?: number;
}
}
# 基于向后查看 tsconfig.json 的 fs 運行編譯
$ tsc
# 使用編譯器默認值僅為 index.ts 發射 JS
$ tsc index.ts
# 使用默認設置為文件夾 src 中的任何 .ts 文件發出 JS
$ tsc src/*.ts
# 使用 tsconfig.production.json 中的編譯器設置發出引用的文件
$ tsc --project tsconfig.production.json
# 為 js 文件發出 d.ts 文件,顯示布爾值的編譯器選項
$ tsc index.js --declaration --emitDeclarationOnly
# 通過采用字符串參數的編譯器選項從兩個文件發出單個 .js 文件
$ tsc app.ts util.ts --target esnext --outfile index.js
:- | -- |
---|---|
--all boolean | 顯示所有編譯器選項 |
--generateTrace string | 生成事件跟蹤和類型列表 |
--help boolean | 提供有關 CLI 幫助的本地信息 |
--init boolean | 初始化 TypeScript 項目并創建 tsconfig.json 文件 |
--listFilesOnly boolean | 打印作為編譯一部分的文件名,然后停止處理 |
--locale string | 設置來自 TypeScript 的消息傳遞語言。 這不影響發射 |
--project string | 編譯項目給定其配置文件的路徑,或帶有 'tsconfig.json' 的文件夾 |
--showConfig boolean | 打印最終配置而不是構建 |
--version boolean | 打印編譯器的版本 |
:- | -- |
---|---|
--build boolean | 構建一個或多個項目及其依賴項(如果已過期) |
--clean boolean | 刪除所有項目的輸出 |
--dry boolean | 顯示將構建的內容(或刪除,如果使用“--clean”指定) |
--force boolean | 構建所有項目,包括那些看起來是最新的項目 |
--verbose boolean | 啟用詳細日志記錄 |
:- | -- |
---|---|
--excludeDirectories list | 從監視進程中刪除目錄列表 |
--excludeFiles list | 從監視模式的處理中刪除文件列表 |
--fallbackPolling fixedinterval, priorityinterval, dynamicpriority, fixedchunksize | 指定當系統用完本機文件觀察器時觀察器應使用的方法 |
--synchronousWatchDirectory boolean | 在本機不支持遞歸監視的平臺上同步調用回調并更新目錄監視程序的狀態 |
--watch boolean | 觀看輸入文件 |
--watchDirectory usefsevents, fixedpollinginterval, dynamicprioritypolling, _fixedchunksizepolling | 指定在缺少遞歸文件監視功能的系統上如何監視目錄 |
--watchFile fixedpollinginterval, prioritypollinginterval, dynamicprioritypolling, fixedchunksizepolling, usefsevents, usefseventsonparentdirectory | 指定 TypeScript 監視模式的工作方式 |
:- | -- |
---|---|
files | 指定要包含 在程序中的文件的允許列表 |
extends | 包含要繼承 的另一個配置文件的路徑 |
include | 指定要包含 在程序中的文件名或模式數組 |
exclude | 指定解析包含時應跳過 的文件名或模式數組 |
references | 項目引用是一種將 TypeScript 程序構造成更小部分的方法 |
{
"extends": "./tsconfig",
"compilerOptions": {
"strictNullChecks": false
}
}
:- | -- |
---|---|
allowUnreachableCode | 允許無法訪問的代碼 |
allowUnusedLabels | 允許未使用的標簽 |
alwaysStrict | 始終嚴格 |
exactOptionalPropertyTypes | 啟用后,TypeScript 應用更嚴格的規則來處理它如何處理類型或具有 ? 字首 |
noFallthroughCasesInSwitch | 在 switch 語句中報告失敗案例的錯誤 |
noImplicitAny | 在某些不存在類型注釋的情況下,TypeScript 將在無法推斷類型時回退到變量的任何類型 |
noImplicitOverride | 當處理使用繼承的類時,子類可能與在基類中重命名時重載的函數“不同步” |
noImplicitReturns | 沒有隱式返回 |
noImplicitThis | 使用隱含的“any”類型在“this”表達式上引發錯誤 |
noPropertyAccessFromIndexSignature | 此設置確保通過“點”(obj.key)語法訪問字段和“索引”(obj[“key”])以及在類型中聲明屬性的方式之間的一致性 |
noUncheckedIndexedAccess | TypeScript 有一種方法可以通過索引簽名來描述對象上具有未知鍵但已知值的對象 |
noUnusedLocals | 報告未使用的局部變量的錯誤 |
noUnusedParameters | 報告函數中未使用參數的錯誤 |
strict | 嚴格標志啟用了范圍廣泛的類型檢查行為,從而更有效地保證了程序的正確性 |
strictBindCallApply | TypeScript 將檢查函數調用、綁定和應用的內置方法是否使用底層函數的正確參數調用 |
strictFunctionTypes | 此標志會導致更正確地檢查函數參數 |
strictNullChecks | 嚴格的空檢查 |
strictPropertyInitialization | 嚴格的屬性初始化 |
useUnknownInCatchVariables | 在 TypeScript 4.0 中,添加了支持以允許將 catch 子句中的變量類型從 any 更改為 unknown |
:- | -- |
---|---|
allowUmdGlobalAccess | 為 true 時,將允許你在模塊文件中以全局變量的形式訪問 UMD 的導出 |
baseUrl | 可以讓您設置解析非絕對路徑模塊名時的基準目錄 |
module | 設置程序的模塊系統 |
moduleResolution | 指定模塊解析策略:'node'(Node.js)或 'classic' |
moduleSuffixes | 提供一種在解析模塊時覆蓋要搜索的默認文件名后綴列表的方法 |
noResolve | 默認情況下,TypeScript 將檢查導入和 <reference 指令的初始文件集,并將這些解析的文件添加到您的程序中 |
paths | 一些將模塊導入重新映射到相對于 baseUrl 路徑的配置 |
resolveJsonModule | 允許導入帶有“.json”擴展名的模塊,這是 node 項目中的常見做法 |
rootDir | 默認: 所有輸入的非聲明文件中的最長公共路徑 |
rootDirs | 通過 rootDirs,你可以告訴編譯器有許多“虛擬”的目錄作為一個根目錄 |
typeRoots | 默認情況下,所有 可見 的 ”@types” 包都將包含在你的編譯過程中 |
types | 默認情況下,所有 可見 的 ”@types” 包都將包含在你的編譯過程中 |
:- | -- |
---|---|
declaration | 為項目中的每個 TypeScript 或 JavaScript 文件生成 .d.ts 文件 |
declarationDir | 提供一種配置發出聲明文件的根目錄的方法 |
declarationMap | 為映射回原始 .ts 源文件的 .d.ts 文件生成源映射 |
downlevelIteration | 降級是 TypeScript 的術語,用于轉譯到舊版本的 JavaScript |
emitBOM | 控制 TypeScript 在寫入輸出文件時是否會發出字節順序標記 (BOM) |
emitDeclarationOnly | 只發出 .d.ts 文件;不要發出 .js 文件 |
importHelpers | 對于某些降級操作,TypeScript 使用一些輔助代碼來執行擴展類、展開數組或對象以及異步操作等操作 |
importsNotUsedAsValues | 此標志控制導入的工作方式,有 3 個不同的選項: remove , preserve , error |
inlineSourceMap | 設置后,TypeScript 不會寫出 .js.map 文件來提供源映射,而是將源映射內容嵌入到 .js 文件中 |
inlineSources | 設置后,TypeScript 會將 .ts 文件的原始內容作為嵌入字符串包含在源映射中(使用源映射的 sourcesContent 屬性) |
mapRoot | 指定調試器應該定位映射文件而不是生成位置的位置 |
newLine | 指定發出文件時要使用的行尾順序:“CRLF”(dos)或“LF”(unix) |
noEmit | 不要發出編譯器輸出文件,如 JavaScript 源代碼、源映射或聲明 |
noEmitHelpers | 您可以在全局范圍內為您使用的助手提供實現,并完全關閉助手函數的發出,而不是使用 importHelpers 導入助手 |
noEmitOnError | 如果報告了任何錯誤,請不要發出編譯器輸出文件,如 JavaScript 源代碼、源映射或聲明 |
outDir | 如果指定,.js(以及 .d.ts、.js.map 等)文件將被發送到此目錄中 |
outFile | 如果指定,所有全局(非模塊)文件將連接到指定的單個輸出文件中 |
preserveConstEnums | 不要刪除生成的代碼中的 const enum 聲明 |
preserveValueImports | 在某些情況下,TypeScript 無法檢測到您正在使用導入 |
removeComments | 轉換為 JavaScript 時從 TypeScript 文件中刪除所有注釋 |
sourceMap | 啟用源映射文件的生成 |
sourceRoot | 指定調試器應定位 TypeScript 文件的位置,而不是相對源位置 |
stripInternal | 不要為在其 JSDoc 注釋中具有 @internal 注釋的代碼發出聲明 |
:- | -- |
---|---|
allowJs | 允許 JavaScript 文件在你的工程中被引入,而不是僅僅允許 .ts 和 .tsx 文件 |
checkJs | 與 allowJs 配合使用,當 checkJs 被啟用時,JavaScript 文件中會報告錯誤 |
maxNodeModuleJsDepth | 在 node_modules 下搜索和加載 JavaScript 文件的最大依賴深度 |
:- | -- |
---|---|
disableSizeLimit | 分配的內存量有一個上限。打開此標志將刪除限制 |
plugins | 可在編輯器內運行的語言服務插件列表 |
:- | -- |
---|---|
allowSyntheticDefaultImports | 允許合成默認導入 |
esModuleInterop | ES 模塊互操作 |
forceConsistentCasingInFileNames | 在文件名中強制使用一致的大小寫 |
isolatedModules | 隔離模塊 |
preserveSymlinks | 保留符號鏈接 |
:- | -- |
---|---|
charset | 在早期版本的 TypeScript 中,這控制了從磁盤讀取文本文件時使用的編碼 |
keyofStringsOnly | 此標志將 keyof 類型運算符更改為返回 string 而不是 `string |
noImplicitUseStrict | 默認情況下,當向非 ES6 目標發出模塊文件時,TypeScript 發出"use strict" ;文件頂部的序言。此設置禁用序言 |
noStrictGenericChecks | TypeScript 在比較兩個泛型函數時會統一類型參數 |
out | 請改用 outFile |
suppressExcessPropertyErrors | 抑制過多的屬性錯誤 |
suppressImplicitAnyIndexErrors | 抑制隱式任何索引錯誤 |
:- | -- |
---|---|
skipDefaultLibCheck | 請改用 skipLibCheck |
skipLibCheck | 跳過聲明文件的類型檢查 |
:- | -- |
---|---|
emitDecoratorMetadata | 發射裝飾器元數據 |
experimentalDecorators | 實驗裝飾器 |
jsx | 控制 JSX 在 JavaScript 文件中的輸出方式 |
jsxFactory | 使用經典 JSX 運行時編譯 JSX 元素時更改在 .js 文件中調用的函數 |
jsxFragmentFactory | 指定在使用 jsxFactory 編譯器選項指定 react JSX emit 時要使用的 JSX 片段工廠函數,例如 Fragment |
jsxImportSource | 聲明模塊說明符用于在將 jsx 用作 TypeScript 4.1 中引入的“react-jsx”或“react-jsxdev”時導入 jsx 和 jsxs 工廠函數 |
lib | TypeScript 包括一組默認的內建 JS 接口(例如 Math)的類型定義,以及在瀏覽器環境中存在的對象的類型定義(例如 document) |
moduleDetection | 模塊檢測 |
noLib | 禁用自動包含任何庫文件 |
reactNamespace | 請改用 jsxFactory |
target | 現代瀏覽器支持全部 ES6 的功能,所以 ES6 是一個不錯的選擇 |
useDefineForClassFields | 為類字段使用定義 |
:- | -- |
---|---|
noErrorTruncation | 不要截斷錯誤消息 |
preserveWatchOutput | 保留監視輸出 |
pretty | 使用顏色和上下文對錯誤和消息進行樣式化,默認情況下啟用 |
:- | -- |
---|---|
composite | composite 選項會強制執行某些約束,使得構建工具(包括 在 --build 模式下的 TypeScript 本身)可以快速確定一個工程是否已經建立 |
disableReferencedProjectLoad | 禁用引用項目加載 |
disableSolutionSearching | 禁用解決方案搜索 |
disableSourceOfProjectReferenceRedirect | 禁用源項目引用重定向 |
incremental | 使 TypeScript 將上次編譯的工程圖信息保存到磁盤上的文件中 |
tsBuildInfoFile | 這個選項可以讓您指定一個文件來存儲增量編譯信息,以作為復合工程的一部分,從而可以更快的構建更大的 TypeScript 代碼庫 |
:- | -- |
---|---|
diagnostics | 用于輸出調試信息 |
explainFiles | 打印 TypeScript 視為項目一部分的文件的名稱以及它們是編譯一部分的原因 |
extendedDiagnostics | 您可以使用此標志來發現 TypeScript 在編譯時將時間花在哪里 |
generateCpuProfile | 此選項使您有機會讓 TypeScript 在編譯器運行期間發出 v8 CPU 配置文件 |
listEmittedFiles | 將編譯過程中生成的文件的名稱打印到終端 |
listFiles | 打印編譯部分文件的名稱 |
traceResolution | 當您嘗試調試未包含模塊的原因時 |
:- | -- |
---|---|
watchFile | 如何監視單個文件的策略 |
watchDirectory | 在缺乏遞歸文件監視功能的系統下監視整個目錄樹的策略 |
fallbackPolling | 使用文件系統事件時,此選項指定當系統用完本機文件觀察器和/或不支持本機文件觀察器時使用的輪詢策略 |
synchronousWatchDirectory | 在本機不支持遞歸監視的平臺上同步調用回調并更新目錄監視程序的狀態 |
excludeDirectories | 您可以使用 excludeFiles 來大幅減少在 --watch 期間監視的文件數量 |
excludeFiles | 您可以使用 excludeFiles 從監視的文件中刪除一組特定文件 |
{
"watchOptions": {
"synchronousWatchDirectory": true
}
}
:- | -- |
---|---|
enable | 提供用于在 JavaScript 項目中禁用類型獲取的配置 |
include | 如果您有一個 JavaScript 項目,其中 TypeScript 需要額外的指導來理解全局依賴關系,或者已通過 disableFilenameBasedTypeAcquisition 禁用了內置推理 |
exclude | 提供用于禁用 JavaScript 項目中特定模塊的類型獲取的配置 |
disableFilenameBasedTypeAcquisition | TypeScript 的類型獲取可以根據項目中的文件名推斷出應該添加哪些類型 |
{
"typeAcquisition": {
"enable": false
}
}