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;
}
}
ç±»å¯ä»¥å£°æç´¢å¼ç¾åï¼ä¸å ¶ä»å¯¹è±¡ç±»åçç´¢å¼ç¾åç¸åã
export const Wrapper = forwardRef(
<T extends object>
(
props: RootNodeProps<T>,
ref: React.LegacyRef<HTMLDivElement>
) => {
return (
<div ref={ref}></div>
);
}
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 ç±»åçæ è®°ã 请注æï¼å¿ é¡»å¯ç¨ noImplicitThis æ å¿æè½ä½¿ç¨æ¤å®ç¨ç¨åºã
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 = React.forwardRef<HTMLUListElement, MenuProps>((props, ref) => (
<ul {...props} ref={ref} />
));
type MenuComponent = typeof InternalMenu & {
Item: typeof MenuItem; // MenuItem 彿°ç»ä»¶
SubMenu: typeof SubMenu; // SubMenu 彿°ç»ä»¶
};
const Menu: MenuComponent = 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)
import React, { ElementType, ComponentPropsWithoutRef } from "react";
export const Link = <T extends ElementType<any> = "a">(
props: { as?: T; } & ComponentPropsWithoutRef<T>
) => {
const Comp = props.as || "a";
return <Comp {...props}></Comp>;
};
<Link as="div">ææ¬</Link>;
å
è®¸ä¼ å
¥èªå®ä¹ React ç»ä»¶ï¼æ div, a æ ç¾
type RowProps = {
element: React.ElementType<{
className?: string;
}>;
}
const Row = (props: RowProps) => {
return (
<props.element className="h-8 w-8" />
);
};
<Row element={"div"} />;
<Row element={UserIcon} />;
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;
type Arrayish = {
[n: number]: unknown;
};
type A = keyof Arrayish;
// type A = number
const named = ["aqua", "aquamarine", "azure"] as const;
const hex = ["#00FFFF", "#7FFFD4", "#F0FFFF"] as const;
type Colors = {
[key in (typeof named)[number]]: (typeof hex)[number];
};
// Colors = {
// aqua: "#00FFFF" | "#7FFFD4" | "#F0FFFF";
// ....
// }
interface NumberOrString {
[index: string]: string | number;
length: number;
name: string;
}
const point = [3, 4] as const
// type 'readonly [3, 4]'
type Point = { x: number; y: number; }
type Data = Point[];
// Data æ¯ä¸ªæ°ç»ï¼æåéé¢çå
ç´ ç±»å
type PointDetail = Data[number];
// type PointDetail = { x: number; y: number; }
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;
}
const MyArray = [
{ name: "Alice", age: 15 },
{ name: "Bob", age: 23 },
{ name: "Eve", age: 38 },
];
type Person = typeof MyArray[number];
// type Person = {
// name: string;
// age: number;
// }
type Age = typeof MyArray[number]["age"];
// type Age = number
type Age2 = Person["age"];
// type Age2 = number
const a = <T extends string>(t: T) => t;
const b = <T extends number>(t: T) => t;
const c = <T extends boolean>(t: T) => t;
const d = a("a"); // const d: 'a'
const e = b(1); // const d: 1
const f = c(true); // const d: true
è¿étçç±»åç¨äºä¸ä¸ªå±å¼è¿ç®
const g =
<T extends string[]>(t: [...T]) => t;
ç±»ååæ["111", "222"]äº
const h = g(["111", "222"]);
const keys = Object.keys(options) as (keyof typeof options)[];
keys.forEach(key => {
if (options[key] == null) {
throw new Error(`Missing option ${key}`);
}
});
type Color = "primary" | "secondary" | string;
ä¿®æ¹æä¸é¢ä»£ç ï¼æä»£ç 䏿æç¤º
type Color = "primary" | "secondary" | (string & {});
ä¾å¦ï¼å½æ¨æ³ä½¿ç¨æ©å±å¦ä¸ä¸ªåºç 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;
}
}
/** @type {string} */
var s;
/** @type {Window} */
var win;
/** @type {PromiseLike<string>} */
var promisedString;
// æ¨å¯ä»¥æå®å
·æ DOM 屿§ç HTML å
ç´
/** @type {HTMLElement} */
var elm = document.querySelector(selector);
elm.dataset.myData = "";
/** @type {number[]} */
var ns;
/** @type {Array.<number>} */
var jsdoc;
/** @type {Array<number>} */
var nas;
/** @type {string | boolean} */
var sb;
/** @type {{ a: string, b: number }} */
var var9;
/**
* å°ä»»æâå符串â屿§æ å°å°âæ°åâçç±»å°å¾å¯¹è±¡
* @type {Object.<string, number>}
*/
var stringToNumber;
/** @type {Object.<number, object>} */
var arrayLike;
/** @type {function(string, boolean): number} Closure syntax */
var sbn;
/** @type {(s: string, b: boolean) => number} TypeScript syntax */
var sbn2;
/** @type {Function} */
var fn7;
/** @type {function} */
var fn6;
/**
* @type {*} - can be 'any' type
*/
var star;
/**
* @type {?} - unknown type (same as 'any')
*/
var question;
/** @type {number | string} */
var numberOrString = Math.random() < 0.5 ? "hello" : 100;
var typeAssertedNumber = /** @type {number} */ (numberOrString);
let one = /** @type {const} */(1);
// @filename: types.d.ts
export type Pet = {
name: string,
};
// @filename: main.js
/** @param { import("./types").Pet } p */
function walk(p) {
console.log(`Walking ${p.name}...`);
}
å¯¼å ¥ç±»åå¯ä»¥å¨ç±»åå«å声æä¸ä½¿ç¨
/**
* @typedef {import("./types").Pet} Pet
*/
/** @type {Pet} */
var myPet;
myPet.name;
妿æ¨ä¸ç¥éç±»åï¼æè
妿宿ä¸ä¸ªå¾ç¦äººç大类åï¼import types å¯ä»¥ç¨æ¥ä»æ¨¡åä¸è·åå¼çç±»åï¼
/**
* @type {typeof import("./accounts").userAccount}
*/
var x = require("./accounts").userAccount;
/**
* @param {string} p1 - ä¸ä¸ªåç¬¦ä¸²åæ°
* @param {string=} p2 - å¯éåæ°ï¼Google Closure è¯æ³ï¼
* @param {string} [p3] - å¦ä¸ä¸ªå¯éåæ°ï¼JSDoc è¯æ³ï¼
* @param {string} [p4="test"] - å
·æé»è®¤å¼çå¯éåæ°
* @returns {string} è¿æ¯ç»æ
*/
function stringsStrings(p1, p2, p3, p4) {
// TODO
}
åæ ·ï¼å¯¹äºå½æ°çè¿åç±»åï¼
/**
* @return {PromiseLike<string>}
*/
function ps() {}
/**
* @returns {{ a: string, b: number }} - å¯ä»¥ä½¿ç¨â@returnsâåâ@returnâ
*/
function ab() {}
/**
* @typedef {Object} SpecialType - å建ä¸ä¸ªå为âSpecialTypeâçæ°ç±»å
* @property {string} prop1 - SpecialType çåç¬¦ä¸²å±æ§
* @property {number} prop2 - SpecialType çæ°å屿§
* @property {number=} prop3 - SpecialType çå¯éæ°å屿§
* @prop {number} [prop4] - SpecialType çå¯éæ°å屿§
* @prop {number} [prop5=42] - å
·æé»è®¤å¼ç SpecialType çå¯éæ°å屿§
*/
/** @type {SpecialType} */
var specialTypeObject;
specialTypeObject.prop3;
æ¨å¯ä»¥å¨ç¬¬ä¸è¡ä½¿ç¨ object æ Object
/**
* @typedef {object} SpecialType1 - å建ä¸ä¸ªå为âSpecialTypeâçæ°ç±»å
* @property {string} prop1 - SpecialType çåç¬¦ä¸²å±æ§
* @property {number} prop2 - SpecialType çæ°å屿§
* @property {number=} prop3 - SpecialType çå¯éæ°å屿§
*/
/** @type {SpecialType1} */
var specialTypeObject1;
@param å è®¸å¯¹ä¸æ¬¡æ§ç±»åè§è使ç¨ç±»ä¼¼çè¯æ³ã 请注æï¼åµå¥ç屿§åç§°å¿ é¡»ä»¥åæ°å称为åç¼ï¼
/**
* @param {Object} options - å½¢ç¶åä¸é¢çSpecialType䏿 ·
* @param {string} options.prop1
* @param {number} options.prop2
* @param {number=} options.prop3
* @param {number} [options.prop4]
* @param {number} [options.prop5=42]
*/
function special(options) {
return (options.prop4 || 1001) + options.prop5;
}
@callback ç±»ä¼¼äº @typedefï¼ä½å®æå®çæ¯å½æ°ç±»åè䏿¯å¯¹è±¡ç±»åï¼
/**
* @callback Predicate
* @param {string} data
* @param {number} [index]
* @returns {boolean}
*/
/** @type {Predicate} */
const ok = (s) => !(s.length % 2);
å½ç¶ï¼è¿äºç±»åä¸çä»»ä½ä¸ç§é½å¯ä»¥å¨åè¡ @typedef ä¸ä½¿ç¨ TypeScript è¯æ³å£°æï¼
/** @typedef {{ prop1: string, prop2: string, prop3?: number }} SpecialType */
/** @typedef {(data: string, index?: number) => boolean} Predicate */
æ¨å¯ä»¥ä½¿ç¨ @template æ 记声æç±»ååæ°ã è¿ä½¿æ¨å¯ä»¥å建éç¨ç彿°ãç±»æç±»åï¼
/**
* @template T
* @param {T} x - æµåè¿åç±»åçéç¨åæ°
* @returns {T}
*/
function id(x) {
return x;
}
const a = id("string");
const b = id(123);
const c = id({});
使ç¨éå·æå¤ä¸ªæ ç¾æ¥å£°æå¤ä¸ªç±»ååæ°ï¼
/**
* @template T,U,V
* @template W,X
*/
æ¨è¿å¯ä»¥å¨ç±»ååæ°åç§°ä¹åæå®ç±»å约æã åªæå表ä¸ç第ä¸ä¸ªç±»ååæ°åå°çº¦æï¼
/**
* @template {string} K - K å¿
é¡»æ¯å符串æå符串æå
* @template {{ serious(): string }} Seriousalizable - ä¸å®è¦æ serious çæ¹æ³
* @param {K} key
* @param {Seriousalizable} object
*/
function seriousalize(key, object) {
// ????
}
æåï¼æ¨å¯ä»¥ä¸ºç±»ååæ°æå®é»è®¤å¼ï¼
/** @template [T=object] */
class Cache {
/** @param {T} initial */
constructor(T) {
}
}
let c = new Cache()
# åºäºå忥ç 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 çè§æ¨¡å¼ç工使¹å¼ |
"compilerOptions": {
/* åºæ¬é项: */
"esModuleInterop": true,
"skipLibCheck": true,
"target": "es2022",
"verbatimModuleSyntax": true,
"allowJs": true,
"resolveJsonModule": true,
"moduleDetection": "force",
/* ä¸¥æ ¼ */
"strict": true,
"noUncheckedIndexedAccess": true,
/* å¦æä½¿ç¨ TypeScript è¿è¡è½¬è¯ï¼ */
"moduleResolution": "NodeNext",
"module": "NodeNext",
/* 妿ä¸ä½¿ç¨ TypeScript è¿è¡è½¬è¯: */
"moduleResolution": "Bundler",
"module": "ESNext",
"noEmit": true,
/* å¦æä½ ç代ç å¨ DOM ä¸è¿è¡: */
"lib": ["es2022", "dom", "dom.iterable"],
/* å¦æä½ ç代ç ä¸å¨ DOM ä¸è¿è¡: */
"lib": ["es2022"],
/* å¦æä½ æ£å¨æå»ºä¸ä¸ªåº: */
"declaration": true,
/* å¦ææ¨æ£å¨ monorepo ä¸æå»ºåº: */
"composite": true,
"sourceMap": true,
"declarationMap": true
}
| :- | -- |
|---|---|
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 æä»¶çæå¤§ä¾èµæ·±åº¦ |
| :- | -- |
|---|---|
diagnostics # | ç¨äºè¾åºè°è¯ä¿¡æ¯ |
explainFiles # | æå° TypeScript è§ä¸ºé¡¹ç®ä¸é¨åçæä»¶çå称以åå®ä»¬æ¯ç¼è¯ä¸é¨åçåå |
extendedDiagnostics # | æ¨å¯ä»¥ä½¿ç¨æ¤æ å¿æ¥åç° TypeScript å¨ç¼è¯æ¶å°æ¶é´è±å¨åªé |
generateCpuProfile # | æ¤éé¡¹ä½¿æ¨ææºä¼è®© TypeScript å¨ç¼è¯å¨è¿è¡æé´ååº v8 CPU é ç½®æä»¶ |
listEmittedFiles # | å°ç¼è¯è¿ç¨ä¸çæçæä»¶çåç§°æå°å°ç»ç«¯ |
listFiles # | æå°ç¼è¯é¨åæä»¶çåç§° |
traceResolution # | 彿¨å°è¯è°è¯æªå 嫿¨¡åçåå æ¶ |
| :- | -- |
|---|---|
charset # | 卿©æçæ¬ç TypeScript ä¸ï¼è¿æ§å¶äºä»ç£çè¯»åææ¬æä»¶æ¶ä½¿ç¨çç¼ç |
keyofStringsOnly # | æ¤æ å¿å° keyof ç±»åè¿ç®ç¬¦æ´æ¹ä¸ºè¿å string è䏿¯ `string |
noImplicitUseStrict # | é»è®¤æ
åµä¸ï¼å½åé ES6 ç®æ ååºæ¨¡åæä»¶æ¶ï¼TypeScript ååº"use strict"ï¼æä»¶é¡¶é¨çåºè¨ãæ¤è®¾ç½®ç¦ç¨åºè¨ |
noStrictGenericChecks # | TypeScript 卿¯è¾ä¸¤ä¸ªæ³å彿°æ¶ä¼ç»ä¸ç±»ååæ° |
out # | 请æ¹ç¨ outFile |
suppressExcessPropertyErrors # | æå¶è¿å¤ç屿§é误 |
suppressImplicitAnyIndexErrors # | æå¶éå¼ä»»ä½ç´¢å¼é误 |
| :- | -- |
|---|---|
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 # | ä¸ºç±»åæ®µä½¿ç¨å®ä¹ |
| :- | -- |
|---|---|
composite # | composite é项ä¼å¼ºå¶æ§è¡æäºçº¦æï¼ä½¿å¾æå»ºå·¥å ·ï¼å æ¬ å¨ --build 模å¼ä¸ç TypeScript æ¬èº«ï¼å¯ä»¥å¿«éç¡®å®ä¸ä¸ªå·¥ç¨æ¯å¦å·²ç»å»ºç« |
disableReferencedProjectLoad # | ç¦ç¨å¼ç¨é¡¹ç®å è½½ |
disableSolutionSearching # | ç¦ç¨è§£å³æ¹æ¡æç´¢ |
disableSourceOfProjectReferenceRedirect # | ç¦ç¨æºé¡¹ç®å¼ç¨éå®å |
incremental # | 使 TypeScript å°ä¸æ¬¡ç¼è¯çå·¥ç¨å¾ä¿¡æ¯ä¿åå°ç£çä¸çæä»¶ä¸ |
tsBuildInfoFile # | è¿ä¸ªé项å¯ä»¥è®©æ¨æå®ä¸ä¸ªæä»¶æ¥åå¨å¢éç¼è¯ä¿¡æ¯ï¼ä»¥ä½ä¸ºå¤åå·¥ç¨çä¸é¨åï¼ä»èå¯ä»¥æ´å¿«çæå»ºæ´å¤§ç TypeScript 代ç åº |
| :- | -- |
|---|---|
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
}
}