TypeScript 是具有類型語法的 JavaScript。Interface 是為了匹配它們的運(yùn)行時(shí)行為而構(gòu)建的。
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
/** 可選擇從現(xiàn)有接口或類型(Response, HTTPAble)中獲取屬性 */
interface JSONResponse extends Response, HTTPAble {
version: number;
// ?? 附加在編輯器中顯示的 JSDoc 注釋
/** In bytes */
payloadSize: number;
// ?? 此屬性可能不在對象上
outOfStock?: boolean;
// ?? 這是描述作為函數(shù)的屬性的兩種方法
update: (retryTimes: number) => void;
update(retryTimes: number): void;
// ?? 你可以通過 () 調(diào)用這個(gè)對象 -(JS中的函數(shù)是可以調(diào)用的對象)
(): JSONResponse
// ?? 您可以在此 Interface 描述的對象上使用 new
new(s: string): JSONResponse;
// ?? 任何未描述的屬性都假定存在,并且所有屬性必須是數(shù)字
[key: string]: number;
// ?? 告訴 TypeScript 一個(gè)屬性不能被改變
readonly body: string;
}
聲明一個(gè)可以在你的 Interface 中改變的類型
interface APICall<Response> {
data: Response
}
const api: APICall<ArtworkCall> = ...
api.data // Artwork
您可以通過 extends 關(guān)鍵字限制泛型參數(shù)接受的類型。
interface APICall<Response extends { status: number }> {
data: Response
}
const api: APICall<ArtworkCall> = ...
api.data.status
interface Expect {
(matcher: boolean): string
(matcher: string): boolean;
}
一個(gè)可調(diào)用 Interface 可以對不同的參數(shù)集有多個(gè)定義。
interface Syncable {
sync(): void
}
class Account implements Syncable { ... }
您可以通過實(shí)現(xiàn)確保類 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 被合并,多個(gè)聲明將向類型定義添加新字段。
就像您如何在不同范圍內(nèi)創(chuàng)建具有相同名稱的變量一樣,type 具有相似的語義。
TypeScript 包含許多全局類型,它們將幫助您在類型系統(tǒng)中完成常見任務(wù)。檢查他們的網(wǎng)站。
type SanitizedInput = string;
type MissingNo = 404;
主要用于文檔
type Location = {
x: number;
y: number;
};
type Size = "small" | "medium" | "large"
描述許多選項(xiàng)中的一個(gè)類型,例如已知字符串的列表。
type Location = { x: number }
& { y: number }
// { x: number, y: number }
一種合并/擴(kuò)展類型的方法
const data = { ... }
type Data = typeof data
通過 typeof 運(yùn)算符重用來自現(xiàn)有 JavaScript 運(yùn)行時(shí)值的類型。
const createFixtures = () => { ... }
type Fixtures = ReturnType<typeof createFixtures>
function test(fixture: Fixtures) {}
將函數(shù)的返回值重新用作類型。
const data: import("./data").data
這些功能非常適合構(gòu)建庫、描述現(xiàn)有的 JavaScript 代碼,您可能會發(fā)現(xiàn)在大多數(shù) TypeScript 應(yīng)用程序中很少使用它們。
type JSONResponse = {
version: number; // 字段
/** In bytes */ // 附加文檔
payloadSize: number;
outOfStock?: boolean; // 可選的
update: (retryTimes: number) => void; // 箭頭函數(shù)字段
update(retryTimes: number): void; // 函數(shù)
(): JSONResponse // 類型是可調(diào)用的
[key: string]: number; // 接受任何索引
new (s: string): JSONResponse; // new 對象
readonly body: string; // 只讀屬性
}
用于節(jié)省空間的 Terser,請參閱 Interface 備忘清單了解更多信息,除了“static”匹配之外的所有內(nèi)容。
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 }
類似于類型系統(tǒng)的映射語句,允許輸入類型更改新類型的結(jié)構(gòu)。
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
在類型系統(tǒng)中充當(dāng)“if 語句”。 通過泛型創(chuàng)建,然后通常用于減少類型聯(lián)合中的選項(xiàng)數(shù)量。
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'
// }
跟蹤相關(guān)變量
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 幾乎總是采用聯(lián)合,并根據(jù)代碼中的邏輯減少聯(lián)合內(nèi)的類型數(shù)量。
大多數(shù)時(shí)候 CFA 在自然 JavaScript 布爾邏輯中工作,但是有一些方法可以定義您自己的函數(shù),這些函數(shù)會影響 TypeScript 如何縮小類型。
const input = getUserInput()
input // string | number
const inputLength =
(typeof input === "string" && input.length)
|| input
// input: string
在進(jìn)行布爾運(yùn)算時(shí),縮窄也發(fā)生在與代碼相同的行上
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
}
描述影響當(dāng)前范圍的 CFA 更改的函數(shù),因?yàn)樗鼟伋龆皇欠祷?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
// 斷言函數(shù)改變當(dāng)前作用域或拋出
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
}
}
操作符可以安全的檢查一個(gè)對象上是否存在一個(gè)屬性,它通常也被作為類型保護(hù)使用
class ABC { ... }
const abc = new ABC()
新 ABC 的參數(shù)來自構(gòu)造函數(shù)。
前綴 private 是一個(gè)僅類型的添加,在運(yùn)行時(shí)沒有任何影響。 在以下情況下,類之外的代碼可以進(jìn)入項(xiàng)目:
class Bag {
private item: any
}
Vs #private 是運(yùn)行時(shí)私有的,并且在 JavaScript 引擎內(nèi)部強(qiáng)制執(zhí)行,它只能在類內(nèi)部訪問:
class Bag { #item: any }
函數(shù)內(nèi)部‘this’的值取決于函數(shù)的調(diào)用方式。 不能保證始終是您可能在其他語言中使用的類實(shí)例。
您可以使用“此參數(shù)”、使用綁定功能或箭頭功能來解決問題。
一個(gè)類既可以用作類型也可以用作值。
const a:Bag = new Bag()
所以,小心不要這樣做:
class C implements Bag {}
// 確保類符合一組接口或類型 ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈?┈┈╮
// 子類這個(gè)類 ┈┈┈┈┈┈┈┈↘ ┈┈┈┈┈┈┈┈┈┈┈┈┈┴┈┈┈┈┈┈┈
class User extends Account implements Updatable, Serializable {
id: string; // 一個(gè)字段
displayName?: boolean; // 可選字段
name!: string; // '相信我,它在哪里'字段
#attributes: Map<any, any>; // 私人字段
roles = ["user"]; // 具有默認(rèn)值的字段
readonly createdAt = new Date() // 具有默認(rèn)值的只讀字段
// ?? 代碼調(diào)用“new”
constructor(id: string, email: string) {
super(id);
// ?? 在 `strict: true` 中,會根據(jù)字段檢查此代碼以確保其設(shè)置正確
this.email = email;
// ....
};
// ?? 描述類方法(和箭頭函數(shù)字段)的方式
setName(name: string) { this.name = name }
verifyName = (name: string) => { /* ... */ }
// ?? 具有 2 個(gè)重載定義的函數(shù)
sync(): Promise<{ ... }>
sync(cb: ((result: string) => void)): void
sync(cb?: ((result: string) => void)): void | Promise<{ ... }> {}
// ?? Getters 和 setters
get accountID() { }
set accountID(value: string) { }
// ?? 私有訪問只是對這個(gè)類,受保護(hù)的允許子類。 僅用于類型檢查,public 是默認(rèn)值。
private makeRequest() { ... }
protected handleRequest() { ... }
// ?? 靜態(tài)字段/方法
static #userCount = 0;
static registerUser(user: User) { ... }
// ?? 用于設(shè)置靜態(tài)變量的靜態(tài)塊。 ‘this’指的是靜態(tài)類
static { this.#userCount = -1 }
}
聲明一個(gè)可以在你的類方法中改變的類型。
class Box<Type> {
contents: Type
constructor(value: Type) {
this.contents = value;
}
}
const stringBox = new Box("a package")
這些功能是 TypeScript 特定的語言擴(kuò)展,可能永遠(yuǎn)無法使用當(dāng)前語法進(jìn)入 JavaScript。
class Location {
constructor(public x: number, public y: number) {}
}
const loc = new Location(20, 40);
loc.x // 20
loc.y // 40
TypeScript 特定于類的擴(kuò)展,可自動(dòng)將實(shí)例字段設(shè)置為輸入?yún)?shù)。
abstract class Animal {
abstract getName(): string;
printName() {
console.log("Hello, " + this.getName());
}
}
class Dog extends Animal { getName(): { ... } }
一個(gè)類可以被聲明為不可實(shí)現(xiàn),但可以在類型系統(tǒng)中被子類化。 class 成員也可以。
import { Syncable, triggersSync, preferCache, required } from "mylib"
@Syncable
class User {
@triggersSync()
save() { ... }
@preferCache(false)
get displayName() { ... }
update(@required info: Partial<User>) { ... }
}
您可以在類、類方法、訪問器、屬性和方法參數(shù)上使用裝飾器。
class MyClass {
// 最好將索引數(shù)據(jù)存儲在另一個(gè)地方
// 而不是類實(shí)例本身。
[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
這種類型旨在模擬異步函數(shù)中的 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”,因?yàn)樗侵蛔x屬性。
function freeze<Type>(obj: Type)
: Readonly<Type>;
將 Type 中的所有屬性設(shè)為只讀
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 中的所有屬性設(shè)為可選
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>
構(gòu)造一個(gè)具有一組 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 的聯(lián)合成員來構(gòu)造一個(gè)類型。
type T0 = NonNullable<
string | number | undefined
>;
// type T0 = string | number
type T1 = NonNullable<
string[] | null | undefined
>;
// type T1 = string[]
通過從 Type 中排除 null 和 undefined 來構(gòu)造一個(gè)類型。
interface Todo {
name: string;
completed: boolean;
createdAt: number;
}
type TodoPreview = Omit<Todo, "name">;
const todo: TodoPreview = {
completed: false,
createdAt: 1615544252770,
};
todo;
// ?? const todo: TodoPreview
構(gòu)造一個(gè)具有 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
從函數(shù)類型 Type 的參數(shù)中使用的類型構(gòu)造元組類型。
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[]
從構(gòu)造函數(shù)類型的類型構(gòu)造元組或數(shù)組類型。它產(chǎn)生一個(gè)包含所有參數(shù)類型的元組類型(如果 Type 不是函數(shù),則類型 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"
將字符串中的每個(gè)字符轉(zhuǎn)換為大寫版本。
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"
將字符串中的每個(gè)字符轉(zhuǎn)換為等效的小寫字母。
type LowercaseGreeting = "hello, world";
type Greeting = Capitalize<LowercaseGreeting>;
// type Greeting = "Hello, world"
將字符串中的第一個(gè)字符轉(zhuǎn)換為等效的大寫字母。
type UppercaseGreeting = "HELLO WORLD";
type UncomfortableGreeting = Uncapitalize<UppercaseGreeting>;
// type UncomfortableGreeting = "hELLO WORLD"
將字符串中的第一個(gè)字符轉(zhuǎn)換為等效的小寫字母。
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
構(gòu)造一個(gè)由函數(shù) 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);
此實(shí)用程序不返回轉(zhuǎn)換后的類型。 相反,它用作上下文 this 類型的標(biāo)記。 請注意,必須啟用 noImplicitThis 標(biāo)志才能使用此實(shí)用程序。
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
構(gòu)造一個(gè)由 Type 中構(gòu)造函數(shù)的實(shí)例類型組成的類型。
function toHex(this: Number) {
return this.toString(16);
}
function numberToString(
n: ThisParameterType<typeof toHex>
) {
return toHex.apply(n);
}
提取函數(shù)類型的 this 參數(shù)的類型,如果函數(shù)類型沒有 this 參數(shù),則為未知。
function toHex(this: Number) {
return this.toString(16);
}
const fiveToHex
: OmitThisParameter<typeof toHex>
= toHex.bind(5);
console.log(fiveToHex());
從 Type 中移除 this 參數(shù)。 如果 Type 沒有顯式聲明此參數(shù),則結(jié)果只是 Type。 否則,從 Type 創(chuàng)建一個(gè)不帶此參數(shù)的新函數(shù)類型。 泛型被刪除,只有最后一個(gè)重載簽名被傳播到新的函數(shù)類型中。
JSX 規(guī)范是對 ECMAScript 的類似 XML 的語法擴(kuò)展。
.tsx 擴(kuò)展名命名您的文件jsx 選項(xiàng).tsx 文件中使用尖括號類型斷言。const foo = <foo>bar;
// ? 不允許在 .tsx ?? 文件中使用尖括號類型斷言。
const foo = bar as foo;
as 運(yùn)算符在 .ts 和 .tsx 文件中都可用,并且在行為上與尖括號類型斷言樣式相同。
import MyComponent from "./myComponent";
<MyComponent />; // ok
<SomeOtherComponent />; // ? error
基于值的元素只是由范圍內(nèi)的標(biāo)識符查找。
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 />
);
該組件被定義為一個(gè) JavaScript 函數(shù),其第一個(gè)參數(shù)是一個(gè) props 對象。 TS 強(qiáng)制它的返回類型必須可分配給 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 函數(shù)組件
SubMenu: typeof SubMenu; // SubMenu 函數(shù)組件
};
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 />; // ? 有效函數(shù)組件
元素實(shí)例類型必須可以分配給 JSX.ElementClass,否則將導(dǎo)致錯(cuò)誤。
class NotAValidComponent {}
function NotAValidFactoryFunction() {
return {};
}
<NotAValidComponent />; // ? error
<NotAValidFactoryFunction />; // ? error
默認(rèn)情況下,JSX.ElementClass 是 {},但可以對其進(jìn)行擴(kuò)展,以將 JSX 的使用限制為僅限于符合適當(dāng)接口的類型。
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>} />
// 一個(gè)泛型組件
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 是個(gè)數(shù)組,提取里面的元素類型
type PointDetail = Data[number];
// type PointDetail = { x: number; y: number; }
const point = [3, 4] as const
// type 'readonly [3, 4]'
satisfies 允許將驗(yàn)證表達(dá)式的類型與某種類型匹配,而無需更改該表達(dá)式的結(jié)果類型。
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],
};
// 通常的方式會推導(dǎo)出 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>
使用泛型實(shí)例化表達(dá)式:
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;
}
例如,當(dāng)您想使用擴(kuò)展另一個(gè)庫的 JavaScript 代碼時(shí)
import { greeter } from "super-greeter";
// 普通歡迎 API
greeter(2);
greeter("Hello world");
// 現(xiàn)在我們在運(yùn)行時(shí)用一個(gè)新函數(shù)擴(kuò)展對象
import "hyper-super-greeter";
greeter.hyperGreet();
"super-greeter" 的定義:
/* 此示例說明如何為您的函數(shù)設(shè)置多個(gè)重載 */
export interface GreeterFunction {
(name: string): void
(time: number): void
}
/* 此示例顯示如何導(dǎo)出接口指定的函數(shù) */
export const greeter: GreeterFunction;
我們可以像下面這樣擴(kuò)展現(xiàn)有模塊:
/* 導(dǎo)入這個(gè)模塊添加到的模塊 */
import { greeter } from "super-greeter";
/* 聲明與上面導(dǎo)入的模塊相同的模塊,然后我們擴(kuò)展 greeter 函數(shù)的現(xiàn)有聲明 */
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) 此處包含這些調(diào)用簽名 */
declare function myLib(a: string): string;
declare function myLib(a: number): number;
/* 如果你希望這個(gè)庫的名稱是一個(gè)有效的類型名稱,你可以在這里這樣做例如,這允許我們寫 'var x: myLib'; 確保這確實(shí)有意義! 如果沒有,只需刪除此聲明并在下面的命名空間內(nèi)添加類型 */
interface myLib {
name: string;
length: number;
extras?: string[];
}
/* 如果您的庫在全局變量上公開了屬性,請將它們放在此處。 您還應(yīng)該在此處放置類型(接口和類型別名) */
declare namespace myLib {
// 我們可以寫 'myLib.timeout = 50;'
let timeout: number;
// 我們可以訪問 'myLib.version',但不能更改它
const version: string;
// 我們可以通過 'let c = new myLib.Cat(42)' 創(chuàng)建一些類或參考例如 '函數(shù) f(c: myLib.Cat) { ... }
class Cat {
constructor(n: number);
// 我們可以從 'Cat' 實(shí)例中讀取 'c.age'
readonly age: number;
// 我們可以從 'Cat' 實(shí)例調(diào)用 '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;
// 我們可以調(diào)用 'myLib.checkCat(c)' 或 'myLib.checkCat(c, v);'
function checkCat(c: Cat, s?: VetID);
}
import greeter from "super-greeter";
greeter(2);
greeter("Hello world");
要處理通過 UMD 和模塊導(dǎo)入:
/* 如果此模塊是一個(gè) UMD 模塊,在模塊加載器環(huán)境之外加載時(shí)公開全局變量“myFuncLib”,請?jiān)诖颂幝暶髟撊肿兞俊?否則,刪除此聲明 */
export as namespace myFuncLib;
/* 此聲明指定該函數(shù)是從文件中導(dǎo)出的對象 */
export = Greeter;
/* 此示例說明如何為您的函數(shù)設(shè)置多個(gè)重載 */
declare function Greeter(name: string): Greeter.NamedReturnType;
declare function Greeter(length: number): Greeter.LengthReturnType;
如果你也想從你的模塊中公開類型,你可以把它們放在這個(gè)塊中。 通常你會想要描述函數(shù)返回類型的形狀; 如本例所示,應(yīng)在此處聲明該類型,請注意,如果您決定包含此命名空間,則模塊可能會被錯(cuò)誤地導(dǎo)入為命名空間對象,除非 --esModuleInterop 已打開: import * as x from '[~THE MODULE~]'; 錯(cuò)誤的!不要這樣做!
declare namespace Greeter {
export interface LengthReturnType {
width: number;
height: number;
}
export interface NamedReturnType {
firstName: string;
lastName: string;
}
/**
* 如果模塊也有屬性,在這里聲明它們。 例如,這個(gè)聲明說這個(gè)代碼是合法的:
* import f = require('super-greeter');
* console.log(f.defaultName);
*/
export const defaultName: string;
export let defaultLength: number;
}
例如,當(dāng)您想要使用如下所示的 JavaScript 代碼時(shí):
const Greeter = require("super-greeter");
const greeter = new Greeter();
greeter.greet();
要處理通過 UMD 和模塊導(dǎo)入:
export as namespace "super-greeter";
/* 此聲明指定類構(gòu)造函數(shù)是從文件中導(dǎo)出的對象 */
export = Greeter;
/* 在此類中編寫模塊的方法和屬性 */
declare class Greeter {
constructor(customGreeting?: string);
greet: void;
myMethod(opts: MyClass.MyClassMethodOptions): number;
}
如果你也想從你的模塊中公開類型,你可以把它們放在這個(gè)塊中,如果您決定包含此命名空間,則模塊可能會被錯(cuò)誤地導(dǎo)入為命名空間對象,除非 --esModuleInterop 已打開:
import * as x from '[~THE MODULE~]'; 錯(cuò)誤的! 不要這樣做!
declare namespace MyClass {
export interface MyClassMethodOptions {
width?: number;
height?: number;
}
}
# 基于向后查看 tsconfig.json 的 fs 運(yùn)行編譯
$ tsc
# 使用編譯器默認(rèn)值僅為 index.ts 發(fā)射 JS
$ tsc index.ts
# 使用默認(rèn)設(shè)置為文件夾 src 中的任何 .ts 文件發(fā)出 JS
$ tsc src/*.ts
# 使用 tsconfig.production.json 中的編譯器設(shè)置發(fā)出引用的文件
$ tsc --project tsconfig.production.json
# 為 js 文件發(fā)出 d.ts 文件,顯示布爾值的編譯器選項(xiàng)
$ tsc index.js --declaration --emitDeclarationOnly
# 通過采用字符串參數(shù)的編譯器選項(xiàng)從兩個(gè)文件發(fā)出單個(gè) .js 文件
$ tsc app.ts util.ts --target esnext --outfile index.js
| :- | -- |
|---|---|
--all boolean | 顯示所有編譯器選項(xiàng) |
--generateTrace string | 生成事件跟蹤和類型列表 |
--help boolean | 提供有關(guān) CLI 幫助的本地信息 |
--init boolean | 初始化 TypeScript 項(xiàng)目并創(chuàng)建 tsconfig.json 文件 |
--listFilesOnly boolean | 打印作為編譯一部分的文件名,然后停止處理 |
--locale string | 設(shè)置來自 TypeScript 的消息傳遞語言。 這不影響發(fā)射 |
--project string | 編譯項(xiàng)目給定其配置文件的路徑,或帶有 'tsconfig.json' 的文件夾 |
--showConfig boolean | 打印最終配置而不是構(gòu)建 |
--version boolean | 打印編譯器的版本 |
| :- | -- |
|---|---|
--build boolean | 構(gòu)建一個(gè)或多個(gè)項(xiàng)目及其依賴項(xiàng)(如果已過期) |
--clean boolean | 刪除所有項(xiàng)目的輸出 |
--dry boolean | 顯示將構(gòu)建的內(nèi)容(或刪除,如果使用“--clean”指定) |
--force boolean | 構(gòu)建所有項(xiàng)目,包括那些看起來是最新的項(xiàng)目 |
--verbose boolean | 啟用詳細(xì)日志記錄 |
| :- | -- |
|---|---|
--excludeDirectories list | 從監(jiān)視進(jìn)程中刪除目錄列表 |
--excludeFiles list | 從監(jiān)視模式的處理中刪除文件列表 |
--fallbackPolling fixedinterval, priorityinterval, dynamicpriority, fixedchunksize | 指定當(dāng)系統(tǒng)用完本機(jī)文件觀察器時(shí)觀察器應(yīng)使用的方法 |
--synchronousWatchDirectory boolean | 在本機(jī)不支持遞歸監(jiān)視的平臺上同步調(diào)用回調(diào)并更新目錄監(jiān)視程序的狀態(tài) |
--watch boolean | 觀看輸入文件 |
--watchDirectory usefsevents, fixedpollinginterval, dynamicprioritypolling, _fixedchunksizepolling | 指定在缺少遞歸文件監(jiān)視功能的系統(tǒng)上如何監(jiān)視目錄 |
--watchFile fixedpollinginterval, prioritypollinginterval, dynamicprioritypolling, fixedchunksizepolling, usefsevents, usefseventsonparentdirectory | 指定 TypeScript 監(jiān)視模式的工作方式 |
| :- | -- |
|---|---|
allowUnreachableCode # | 允許無法訪問的代碼 |
allowUnusedLabels # | 允許未使用的標(biāo)簽 |
alwaysStrict # | 始終嚴(yán)格 |
exactOptionalPropertyTypes # | 啟用后,TypeScript 應(yīng)用更嚴(yán)格的規(guī)則來處理它如何處理類型或具有 ? 字首 |
noFallthroughCasesInSwitch # | 在 switch 語句中報(bào)告失敗案例的錯(cuò)誤 |
noImplicitAny # | 在某些不存在類型注釋的情況下,TypeScript 將在無法推斷類型時(shí)回退到變量的任何類型 |
noImplicitOverride # | 當(dāng)處理使用繼承的類時(shí),子類可能與在基類中重命名時(shí)重載的函數(shù)“不同步” |
noImplicitReturns # | 沒有隱式返回 |
noImplicitThis # | 使用隱含的“any”類型在“this”表達(dá)式上引發(fā)錯(cuò)誤 |
noPropertyAccessFromIndexSignature # | 此設(shè)置確保通過“點(diǎn)”(obj.key)語法訪問字段和“索引”(obj[“key”])以及在類型中聲明屬性的方式之間的一致性 |
noUncheckedIndexedAccess # | TypeScript 有一種方法可以通過索引簽名來描述對象上具有未知鍵但已知值的對象 |
noUnusedLocals # | 報(bào)告未使用的局部變量的錯(cuò)誤 |
noUnusedParameters # | 報(bào)告函數(shù)中未使用參數(shù)的錯(cuò)誤 |
strict # | 嚴(yán)格標(biāo)志啟用了范圍廣泛的類型檢查行為,從而更有效地保證了程序的正確性 |
strictBindCallApply # | TypeScript 將檢查函數(shù)調(diào)用、綁定和應(yīng)用的內(nèi)置方法是否使用底層函數(shù)的正確參數(shù)調(diào)用 |
strictFunctionTypes # | 此標(biāo)志會導(dǎo)致更正確地檢查函數(shù)參數(shù) |
strictNullChecks # | 嚴(yán)格的空檢查 |
strictPropertyInitialization # | 嚴(yán)格的屬性初始化 |
useUnknownInCatchVariables # | 在 TypeScript 4.0 中,添加了支持以允許將 catch 子句中的變量類型從 any 更改為 unknown |
| :- | -- |
|---|---|
allowUmdGlobalAccess # | 為 true 時(shí),將允許你在模塊文件中以全局變量的形式訪問 UMD 的導(dǎo)出 |
baseUrl # | 可以讓您設(shè)置解析非絕對路徑模塊名時(shí)的基準(zhǔn)目錄 |
module # | 設(shè)置程序的模塊系統(tǒng) |
moduleResolution | |
moduleSuffixes # | 提供一種在解析模塊時(shí)覆蓋要搜索的默認(rèn)文件名后綴列表的方法 |
noResolve # | 默認(rèn)情況下,TypeScript 將檢查導(dǎo)入和 <reference 指令的初始文件集,并將這些解析的文件添加到您的程序中 |
paths # | 一些將模塊導(dǎo)入重新映射到相對于 baseUrl 路徑的配置 |
resolveJsonModule # | 允許導(dǎo)入帶有“.json”擴(kuò)展名的模塊,這是 node 項(xiàng)目中的常見做法 |
rootDir # | 默認(rèn): 所有輸入的非聲明文件中的最長公共路徑 |
rootDirs # | 通過 rootDirs,你可以告訴編譯器有許多“虛擬”的目錄作為一個(gè)根目錄 |
typeRoots # | 默認(rèn)情況下,所有 可見 的 ”@types” 包都將包含在你的編譯過程中 |
types # | 默認(rèn)情況下,所有 可見 的 ”@types” 包都將包含在你的編譯過程中 |
| :- | -- |
|---|---|
declaration # | 為項(xiàng)目中的每個(gè) TypeScript 或 JavaScript 文件生成 .d.ts 文件 |
declarationDir # | 提供一種配置發(fā)出聲明文件的根目錄的方法 |
declarationMap # | 為映射回原始 .ts 源文件的 .d.ts 文件生成源映射 |
downlevelIteration # | 降級是 TypeScript 的術(shù)語,用于轉(zhuǎn)譯到舊版本的 JavaScript |
emitBOM # | 控制 TypeScript 在寫入輸出文件時(shí)是否會發(fā)出字節(jié)順序標(biāo)記 (BOM) |
emitDeclarationOnly # | 只發(fā)出 .d.ts 文件;不要發(fā)出 .js 文件 |
importHelpers # | 對于某些降級操作,TypeScript 使用一些輔助代碼來執(zhí)行擴(kuò)展類、展開數(shù)組或?qū)ο笠约爱惒讲僮鞯炔僮?/td> |
importsNotUsedAsValues # | 此標(biāo)志控制導(dǎo)入的工作方式,有 3 個(gè)不同的選項(xiàng): remove, preserve, error |
inlineSourceMap # | 設(shè)置后,TypeScript 不會寫出 .js.map 文件來提供源映射,而是將源映射內(nèi)容嵌入到 .js 文件中 |
inlineSources # | 設(shè)置后,TypeScript 會將 .ts 文件的原始內(nèi)容作為嵌入字符串包含在源映射中(使用源映射的 sourcesContent 屬性) |
mapRoot # | 指定調(diào)試器應(yīng)該定位映射文件而不是生成位置的位置 |
newLine # | 指定發(fā)出文件時(shí)要使用的行尾順序:“CRLF”(dos)或“LF”(unix) |
noEmit # | 不要發(fā)出編譯器輸出文件,如 JavaScript 源代碼、源映射或聲明 |
noEmitHelpers # | 您可以在全局范圍內(nèi)為您使用的助手提供實(shí)現(xiàn),并完全關(guān)閉助手函數(shù)的發(fā)出,而不是使用 importHelpers 導(dǎo)入助手 |
noEmitOnError # | 如果報(bào)告了任何錯(cuò)誤,請不要發(fā)出編譯器輸出文件,如 JavaScript 源代碼、源映射或聲明 |
outDir # | 如果指定,.js(以及 .d.ts、.js.map 等)文件將被發(fā)送到此目錄中 |
outFile # | 如果指定,所有全局(非模塊)文件將連接到指定的單個(gè)輸出文件中 |
preserveConstEnums # | 不要?jiǎng)h除生成的代碼中的 const enum 聲明 |
preserveValueImports # | 在某些情況下,TypeScript 無法檢測到您正在使用導(dǎo)入 |
removeComments # | 轉(zhuǎn)換為 JavaScript 時(shí)從 TypeScript 文件中刪除所有注釋 |
sourceMap # | 啟用源映射文件的生成 |
sourceRoot # | 指定調(diào)試器應(yīng)定位 TypeScript 文件的位置,而不是相對源位置 |
stripInternal # | 不要為在其 JSDoc 注釋中具有 @internal 注釋的代碼發(fā)出聲明 |
| :- | -- |
|---|---|
charset # | 在早期版本的 TypeScript 中,這控制了從磁盤讀取文本文件時(shí)使用的編碼 |
keyofStringsOnly # | 此標(biāo)志將 keyof 類型運(yùn)算符更改為返回 string 而不是 `string |
noImplicitUseStrict # | 默認(rèn)情況下,當(dāng)向非 ES6 目標(biāo)發(fā)出模塊文件時(shí),TypeScript 發(fā)出"use strict";文件頂部的序言。此設(shè)置禁用序言 |
noStrictGenericChecks # | TypeScript 在比較兩個(gè)泛型函數(shù)時(shí)會統(tǒng)一類型參數(shù) |
out # | 請改用 outFile |
suppressExcessPropertyErrors # | 抑制過多的屬性錯(cuò)誤 |
suppressImplicitAnyIndexErrors # | 抑制隱式任何索引錯(cuò)誤 |
| :- | -- |
|---|---|
emitDecoratorMetadata # | 發(fā)射裝飾器元數(shù)據(jù) |
experimentalDecorators # | 實(shí)驗(yàn)裝飾器 |
jsx # | 控制 JSX 在 JavaScript 文件中的輸出方式 |
jsxFactory # | 使用經(jīng)典 JSX 運(yùn)行時(shí)編譯 JSX 元素時(shí)更改在 .js 文件中調(diào)用的函數(shù) |
jsxFragmentFactory # | 指定在使用 jsxFactory 編譯器選項(xiàng)指定 react JSX emit 時(shí)要使用的 JSX 片段工廠函數(shù),例如 Fragment |
jsxImportSource # | 聲明模塊說明符用于在將 jsx 用作 TypeScript 4.1 中引入的“react-jsx”或“react-jsxdev”時(shí)導(dǎo)入 jsx 和 jsxs 工廠函數(shù) |
lib # | TypeScript 包括一組默認(rèn)的內(nèi)建 JS 接口(例如 Math)的類型定義,以及在瀏覽器環(huán)境中存在的對象的類型定義(例如 document) |
moduleDetection # | 模塊檢測 |
noLib # | 禁用自動(dòng)包含任何庫文件 |
reactNamespace # | 請改用 jsxFactory |
target # | 現(xiàn)代瀏覽器支持全部 ES6 的功能,所以 ES6 是一個(gè)不錯(cuò)的選擇 |
useDefineForClassFields # | 為類字段使用定義 |
| :- | -- |
|---|---|
composite # | composite 選項(xiàng)會強(qiáng)制執(zhí)行某些約束,使得構(gòu)建工具(包括 在 --build 模式下的 TypeScript 本身)可以快速確定一個(gè)工程是否已經(jīng)建立 |
disableReferencedProjectLoad # | 禁用引用項(xiàng)目加載 |
disableSolutionSearching # | 禁用解決方案搜索 |
disableSourceOfProjectReferenceRedirect # | 禁用源項(xiàng)目引用重定向 |
incremental # | 使 TypeScript 將上次編譯的工程圖信息保存到磁盤上的文件中 |
tsBuildInfoFile # | 這個(gè)選項(xiàng)可以讓您指定一個(gè)文件來存儲增量編譯信息,以作為復(fù)合工程的一部分,從而可以更快的構(gòu)建更大的 TypeScript 代碼庫 |
| :- | -- |
|---|---|
diagnostics # | 用于輸出調(diào)試信息 |
explainFiles # | 打印 TypeScript 視為項(xiàng)目一部分的文件的名稱以及它們是編譯一部分的原因 |
extendedDiagnostics # | 您可以使用此標(biāo)志來發(fā)現(xiàn) TypeScript 在編譯時(shí)將時(shí)間花在哪里 |
generateCpuProfile # | 此選項(xiàng)使您有機(jī)會讓 TypeScript 在編譯器運(yùn)行期間發(fā)出 v8 CPU 配置文件 |
listEmittedFiles # | 將編譯過程中生成的文件的名稱打印到終端 |
listFiles # | 打印編譯部分文件的名稱 |
traceResolution # | 當(dāng)您嘗試調(diào)試未包含模塊的原因時(shí) |
| :- | -- |
|---|---|
watchFile # | 如何監(jiān)視單個(gè)文件的策略 |
watchDirectory # | 在缺乏遞歸文件監(jiān)視功能的系統(tǒng)下監(jiān)視整個(gè)目錄樹的策略 |
fallbackPolling # | 使用文件系統(tǒng)事件時(shí),此選項(xiàng)指定當(dāng)系統(tǒng)用完本機(jī)文件觀察器和/或不支持本機(jī)文件觀察器時(shí)使用的輪詢策略 |
synchronousWatchDirectory # | 在本機(jī)不支持遞歸監(jiān)視的平臺上同步調(diào)用回調(diào)并更新目錄監(jiān)視程序的狀態(tài) |
excludeDirectories # | 您可以使用 excludeFiles 來大幅減少在 --watch 期間監(jiān)視的文件數(shù)量 |
excludeFiles # | 您可以使用 excludeFiles 從監(jiān)視的文件中刪除一組特定文件 |
{
"watchOptions": {
"synchronousWatchDirectory": true
}
}
| :- | -- |
|---|---|
enable # | 提供用于在 JavaScript 項(xiàng)目中禁用類型獲取的配置 |
include # | 如果您有一個(gè) JavaScript 項(xiàng)目,其中 TypeScript 需要額外的指導(dǎo)來理解全局依賴關(guān)系,或者已通過 disableFilenameBasedTypeAcquisition 禁用了內(nèi)置推理 |
exclude # | 提供用于禁用 JavaScript 項(xiàng)目中特定模塊的類型獲取的配置 |
disableFilenameBasedTypeAcquisition # | TypeScript 的類型獲取可以根據(jù)項(xiàng)目中的文件名推斷出應(yīng)該添加哪些類型 |
{
"typeAcquisition": {
"enable": false
}
}
感谢您访问我们的网站,您可能还对以下资源感兴趣:
国产成人精品999视频&日本一区二区亚洲人妻精品&久久久精品国产99久久精&99热这里只有成人精品国产&精品国产剧情av一区二区&成人亚洲精品久久久久app&国产精品美女高潮抽搐A片