рдЯрд╛рдЗрдкрдкреНрд░рддрд┐ред рдкрд╛рд╡рд░ рдХрднреА рдирд╣реАрдВ

рдЬрдм рдореИрдВрдиреЗ рдкрд╣рд▓реА рдмрд╛рд░ рд╢рдмреНрдж рдХрднреА рдирд╣реАрдВ рджреЗрдЦрд╛, рддреЛ рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдмреЗрдХрд╛рд░ рдХреИрд╕реЗ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред рд╕рдордп рдХреЗ рд╕рд╛рде, ts рдореЗрдВ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдбреВрдмрддреЗ рд╣реБрдП, рдореИрдВ рдпрд╣ рд╕рдордЭрдиреЗ рд▓рдЧрд╛ рдХрд┐ рдпрд╣ рд╢рдмреНрдж рдХрд┐рддрдирд╛ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╣реИред рдФрд░ рдпрд╣ рд╢рдХреНрддрд┐ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рд╕реЗ рдкреИрджрд╛ рд╣реБрдИ рд╣реИ рдЬрд┐рд╕реЗ рдореИрдВ рдкрд╛рдардХ рдХреЗ рд╕рд╛рде рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХрд╛ рдЗрд░рд╛рджрд╛ рд░рдЦрддрд╛ рд╣реВрдВред рдХреМрди рдкрд░рд╡рд╛рд╣ рдХрд░рддрд╛ рд╣реИ, рдмрд┐рд▓реНрд▓реА рдореЗрдВ рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред

рдХреНрдпрд╛ рдХрднреА рдирд╣реАрдВ рд╣реИ


рдпрджрд┐ рд╣рдо рдЗрддрд┐рд╣рд╛рд╕ рдореЗрдВ рдбреБрдмрдХреА рд▓рдЧрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рдВрд╕реНрдХрд░рдг реи.реж рдХреЗ рднреЛрд░ рдореЗрдВ рдХрднреА рдирд╣реАрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛, рдмрд▓реНрдХрд┐ рдЗрд╕рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдорд╛рдореВрд▓реА рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рдеред рдпрджрд┐ рдЖрдк рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдФрд░ рдЖрдЬрд╝рд╛рджреА рд╕реЗ ts рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдкреБрдирдГ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░рдХрд╛рд░ рдХрднреА рднреА рдПрдХ рдЖрджрд┐рдо рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рд╣реИ рдЬреЛ рдЙрди рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрдд рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдХрднреА рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдпрд╛, рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрдд рдЬреЛ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдХрднреА рдирд╣реАрдВ рд▓реМрдЯрд╛рдПрдЧрд╛, рдпрд╛ рддреЛ рдЗрд╕рдХреЗ рд▓реВрдк рдХреЗ рдХрд╛рд░рдг, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЕрдирдВрдд рд▓реВрдк, рдпрд╛ рдЗрд╕рдХреЗ рд░реБрдХрд╛рд╡рдЯ рдХреЗ рдХрд╛рд░рдгред рдФрд░ рдЬреЛ рдХрд╣рд╛ рдЧрдпрд╛ рдерд╛ рдЙрд╕рдХрд╛ рд╕рд╛рд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдиреАрдЪреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦрдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реВрдВ:

/**    */ function error(message: string): never { throw new Error(message); } /**   */ function infiniteLoop(): never { while (true) { } } /**   */ function infiniteRec(): never { return infiniteRec(); } 

рд╢рд╛рдпрдж рдЗрд╕ рддрд░рд╣ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рдХрд╛рд░рдг, рдореБрдЭреЗ рдкрд╣рд▓реА рдзрд╛рд░рдгрд╛ рдорд┐рд▓реА рдХрд┐ рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдкреНрд░рдХрд╛рд░ рдкреНрд░рдгрд╛рд▓реА


рдЕрдм рдореИрдВ рдХрд╣ рд╕рдХрддрд╛ рд╣реВрдБ рдХрд┐ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд╕рдореГрджреНрдз рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдЧреБрдг рдХрднреА рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдФрд░ рдЕрдкрдиреЗ рд╢рдмреНрджреЛрдВ рдХреЗ рд╕рдорд░реНрдерди рдореЗрдВ рдореИрдВ lib.es5.d.ts рд╕реЗ рдХрдИ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдкреНрд░рдХрд╛рд░ рджреВрдВрдЧрд╛

 /** Exclude from T those types that are assignable to U */ type Exclude<T, U> = T extends U ? never : T; /** Extract from T those types that are assignable to U */ type Extract<T, U> = T extends U ? T : never; /** Construct a type with the properties of T except for those in type K. */ type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>; /** Exclude null and undefined from T */ type NonNullable<T> = T extends null | undefined ? never : T; /** Obtain the parameters of a function type in a tuple */ type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never; 

рдореЗрд░реЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде, рдореИрдВ рдЕрдкрдирд╛ рдкрд╕рдВрджреАрджрд╛ рдирд╣реАрдВ рджреЗ рдкрд╛рдКрдВрдЧрд╛ - рдЧреЗрдЯрдиреЗрдо, рдХреАрдл рдХрд╛ рдмреЗрд╣рддрд░ рдПрдирд╛рд▓реЙрдЧ:

 /** * GetNames      * @template FromType  -   * @template KeepType   * @template Include       .   false -    KeepType */ type GetNames<FromType, KeepType = any, Include = true> = { [K in keyof FromType]: FromType[K] extends KeepType ? Include extends true ? K : never : Include extends true ? never : K }[keyof FromType]; //   class SomeClass { firstName: string; lastName: string; age: number; count: number; getData(): string { return "dummy"; } } // be: "firstName" | "lastName" type StringKeys = GetNames<SomeClass, string>; // be: "age" | "count" type NumberKeys = GetNames<SomeClass, number>; // be: "getData" type FunctionKeys = GetNames<SomeClass, Function>; // be: "firstName" | "lastName" | "age" | "count" type NonFunctionKeys = GetNames<SomeClass, Function, false>; 

рднрд╡рд┐рд╖реНрдп рдХреЗ рдмрджрд▓рд╛рд╡реЛрдВ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдирд╛


рдЬрдм рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдЬреАрд╡рди рдХреНрд╖рдгрднрдВрдЧреБрд░ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╡рд┐рдХрд╛рд╕ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЪрд░рд┐рддреНрд░ рдкрд░ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВ рдХреЛрдб рдореЗрдВ рдкреНрд░рдореБрдЦ рдмрд┐рдВрджреБрдУрдВ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рд░рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдЗрд╕ рдмрд╛рдд рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдпрд╛ рдЖрдкрдХреА рдЯреАрдо рдХреЗ рд╕рджрд╕реНрдп рд╕рдордп рд▓рдЧрддреЗ рд╣реА рдХреЛрдб рдХрд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЯреБрдХрдбрд╝рд╛ рддрдп рдХрд░рдирд╛ рдирд╣реАрдВ рднреВрд▓реЗрдВрдЧреЗред рдХреЛрдб рдХреЗ рдРрд╕реЗ рдЦрдВрдб рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдкреНрд░рдХрдЯ рд╣реЛрддреЗ рд╣реИрдВ рдЬрдм рдХрд┐рд╕реА рдЪреАрдЬ рдХреА рд╕реНрдерд┐рддрд┐ рдпрд╛ рдЧрдгрдирд╛ рд╣реЛрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЗрдХрд╛рдИ рдкрд░ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдирд╛ред рдореИрдВ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЬреЛ рд╣реЛ рд░рд╣рд╛ рд╣реИ рдЙрд╕рдХреЗ рд╕рдВрджрд░реНрдн рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВред

 //    -   ,     ,   ActionEngine type AdminAction = "CREATE" | "ACTIVATE"; // ,     ,   AdminAction   . class ActionEngine { doAction(action: AdminAction) { switch (action) { case "CREATE": //   return "CREATED"; case "ACTIVATE": //   return "ACTIVATED"; default: throw new Error("   "); } } } 

рдКрдкрд░ рджрд┐рдП рдЧрдП рдХреЛрдб рдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рд╕рд░рд▓реАрдХреГрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ - AdminAction рдкреНрд░рдХрд╛рд░ рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдпрд╣ рднреА рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреА рдЯреАрдо рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рд╣реИред рдЪреВрдВрдХрд┐ рдпрд╣ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдЬреАрд╡рд┐рдд рд░рд╣реЗрдЧреА, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЗ рдПрдХреНрд╢рдирдПрдВрдЧрдЗрди рдХреЛ рдЖрдкрдХреА рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рдмрд┐рдирд╛ AdminAction рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╕реЗ рдмрдЪрд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рд╡реНрдпрдВрдЬрдиреЛрдВ рдХреА рдкреЗрд╢рдХрд╢ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдПрдХ рдХрднреА-рдХрднреА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ NeverError рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдФрд░ doAction рд╡рд┐рдзрд┐ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

 class NeverError extends Error { //         - ts   constructor(value: never) { super(`Unreachable statement: ${value}`); } } class ActionEngine { doAction(action: AdminAction) { switch (action) { case "CREATE": //   return "CREATED"; case "ACTIVATE": //   return "ACTIVATED"; default: throw new NeverError(action); // ^       switch  . } } } 

рдЕрдм AdminAction рдореЗрдВ рдПрдХ рдирдпрд╛ "рдмреНрд▓реЙрдХ" рдорд╛рди рдЬреЛрдбрд╝реЗрдВ рдФрд░ рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдПрдХ рддреНрд░реБрдЯрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ: рдкреНрд░рдХрд╛рд░ рдХрд╛ рддрд░реНрдХ "" рдмреНрд▓реЙрдХ "рдЯрд╛рдЗрдк 'never'ts. (2345) рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реИред

рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рд╣рдордиреЗ рдЗрд╕реЗ рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ред рдпрд╣ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдмрд┐рдВрджреБ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рд╕реНрд╡рд┐рдЪ рдирд┐рд░реНрдорд╛рдг рд╣рдореЗрдВ рдПрдбрдорд┐рди рдПрдХреНрд╢рди рддрддреНрд╡реЛрдВ рдХреЛ рдмрджрд▓рдиреЗ рдпрд╛ рдЙрдиреНрд╣реЗрдВ рд╕реЗрдЯ рд╕реЗ рд╣рдЯрд╛рдиреЗ рд╕реЗ рдмрдЪрд╛рддрд╛ рд╣реИред рдЕрднреНрдпрд╛рд╕ рд╕реЗ, рдореИрдВ рдХрд╣ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдореНрдореАрдж рдХреЗ рдореБрддрд╛рдмрд┐рдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдпрджрд┐ рдЖрдк NeverError рд╡рд░реНрдЧ рдХрд╛ рдкрд░рд┐рдЪрдп рдирд╣реАрдВ рджреЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдХрднреА рднреА рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЪрд░ рдШреЛрд╖рд┐рдд рдХрд░рдХреЗ рдХреЛрдб рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рддрд░рд╣:

 type AdminAction = "CREATE" | "ACTIVATE" | "BLOCK"; class ActionEngine { doAction(action: AdminAction) { switch (action) { case "CREATE": //   return "CREATED"; case "ACTIVATE": //   return "ACTIVATED"; default: const unknownAction: never = action; // Type '"BLOCK"' is not assignable to type 'never'.ts(2322) throw new Error(`   ${unknownAction}`); } } } 

рдкреНрд░рд╕рдВрдЧ рд╕реАрдорд╛: рдпрд╣ + рдХрднреА рдирд╣реАрдВ


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЪрд╛рд▓ рдЕрдХреНрд╕рд░ рдердХрд╛рди рдпрд╛ рд▓рд╛рдкрд░рд╡рд╛рд╣реА рдХреЗ рдмреАрдЪ рдореБрдЭреЗ рд╣рд╛рд╕реНрдпрд╛рд╕реНрдкрдж рдЧрд▓рддрд┐рдпреЛрдВ рд╕реЗ рдмрдЪрд╛рддреА рд╣реИред рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдореИрдВ рдЪреБрдиреЗ рд╣реБрдП рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рдЧреБрдгрд╡рддреНрддрд╛ рдХрд╛ рдЖрдХрд▓рди рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛ред рд╣рдорд╛рд░реЗ рд╕рд╛рде, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдк рдХрд┐рд╕реА рд╡рд░реНрдЧ рдореЗрдВ рдРрд╕реА рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдХрдХреНрд╖рд╛ рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рддрдХ рдкрд╣реБрдБрдЪ рдирд╣реАрдВ рд╣реИред рд╣рд╛рдБ, рдпрд╣ рдбрд░рд╛рд╡рдирд╛ рд▓рдЧрддрд╛ рд╣реИ - рдпрд╣ рд╕рдм gov рд╣реИ ... рдХреЛрдбред

 @SomeDecorator({...}) class SomeUiPanel { @Inject private someService: SomeService; public beforeAccessHook() { //    ,    ,     SomeUiPanel this.someService.doInit("Bla bla"); // ^       :  beforeAccessHook   ,      } } 

рдПрдХ рд╡реНрдпрд╛рдкрдХ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдХреЙрд▓рдмреИрдХ рдпрд╛ рдПрд░реЛ рдлрд╝рдВрдХреНрд╢рдВрд╕ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рдирдХреЗ рдЕрдкрдиреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдВрджрд░реНрдн рд╣реИрдВред рдФрд░ рдХрд╛рд░реНрдп рд╣реИ: рд╕реНрд╡рдпрдВ рдХреЛ рд░рдирдЯрд╛рдЗрдо рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╕реЗ рдХреИрд╕реЗ рдмрдЪрд╛рдпрд╛ рдЬрд╛рдП? рдЗрд╕рдХреЗ рд▓рд┐рдП, рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЗрд╕ рд╕рдВрджрд░реНрдн рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИред

 @SomeDecorator({...}) class SomeUiPanel { @Inject private someService: SomeService; public beforeAccessHook(this: never) { //    ,    ,     SomeUiPanel this.someService.doInit("Bla bla"); // ^ Property 'someService' does not exist on type 'never' } } 

рдирд┐рд╖реНрдкрдХреНрд╖рддрд╛ рдореЗрдВ, рдореИрдВ рдХрд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдХрднреА рднреА рдпреЛрдЧреНрдпрддрд╛ рдирд╣реАрдВ рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдЖрдк рд╢реВрдиреНрдп рдФрд░ {} рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рд╡рд╣ рдкреНрд░рдХрд╛рд░ рд╣реИ рдЬреЛ рдХрднреА рднреА рдХреЛрдб рдХреЛ рдкрдврд╝рдиреЗ рдкрд░ рдзреНрдпрд╛рди рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред

рдЙрдореНрдореАрджреЛрдВ


рдЕрдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓рддрд╛рдУрдВ


рдХрднреА рдирд┐рд╢реНрдЪрд┐рдд рд╡рд┐рдЪрд╛рд░ рди рд╣реЛрдиреЗ рдкрд░, рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХреЛ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП:

 type Maybe<T> = T | void; function invariant<Cond extends boolean>(condition: Cond, message: string): Cond extends true ? void : never { if (condition) { return; } throw new Error(message); } function f(x: Maybe<number>, c: number) { if (c > 0) { invariant(typeof x === "number", "When c is positive, x should be number"); (x + 1); // works because x has been refined to "number" } } 

рд▓реЗрдХрд┐рди рдЕрдлрд╕реЛрд╕ред рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ (x + 1) рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрддрд╛ рд╣реИ: рдСрдкрд░реЗрдЯрд░ '+' рдХреЛ 'рд╢рд╛рдпрдж' рдФрд░ '1' рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдореИрдВ рд╕реНрд╡рдпрдВ рд▓реЗрдЦ рдореЗрдВ рдЬрд╛рд╕реВрд╕реА рдХрд░рддрд╛ рд╣реВрдВ рдЬреЛ рдлреНрд▓реЛ рд╕реЗ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рддрдХ рдХреЛрдб рдХреА 30,000 рд▓рд╛рдЗрдиреЛрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддрд╛ рд╣реИред

рд▓рдЪреАрд▓рд╛ рдмрдВрдзрди


рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рдХрднреА рднреА рдореИрдВ рдЕрдирд┐рд╡рд╛рд░реНрдп рдлрд╝рдВрдХреНрд╢рди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдФрд░ рдХреБрдЫ рд╢рд░реНрддреЛрдВ рдХреЗ рддрд╣рдд, рдЕрдирд╛рд╡рд╢реНрдпрдХ рд▓реЛрдЧреЛрдВ рдХреЛ рдЕрдХреНрд╖рдо рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рд▓реЗрдХрд┐рди рдирд╣реАрдВ, рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛:

 function variants<Type extends number | string>(x: Type, c: Type extends number ? number : never): number { if (typeof x === "number") { return x + c; } return +x; } const three = variants(1, 2); // ok // 2  - never,     string. ,   const one = variants("1"); // expected 2 arguments, but got 1.ts(2554) 

рдЙрдкрд░реЛрдХреНрдд рд╕рдорд╕реНрдпрд╛ рдХреЛ рдПрдХ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЕрдзрд┐рдХ рдХрдареЛрд░ рд╕рддреНрдпрд╛рдкрди


рдореИрдВ ts рд╕рдВрдХрд▓рдХ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдЬреНрдЮрд╛рди рдХреЗ рд╡рд┐рдкрд░реАрдд рдХреБрдЫ рдпрд╛рдж рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред

 variants(<never> {}, <never> {}); 

рдирд┐рд╖реНрдХрд░реНрд╖


рдЕрдВрдд рдореЗрдВ, рдореИрдВ рдЕрдЬреАрдм рд╡рд┐рд╖рдорддрд╛рдУрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╕реЗ, рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдХрд╛рдо рдХреА рдкреЗрд╢рдХрд╢ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдХреМрди рд╕реА рд▓рд╛рдЗрди рддреНрд░реБрдЯрд┐ рд╣реИ?

 class never<never> { never: never; } const whats = new never<string>(); whats.never = ""; 

рд╡рд┐рдХрд▓реНрдк
рдЙрддреНрддрд░рд╛рд░реНрджреНрдз рдореЗрдВ: '' '' рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 'рдХрднреА рдирд╣реАрдВ' рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ (2322)

рдпрд╣реА рд╕рдм рдореИрдВ рдХрднреА рдирд╣реАрдВ рдмрддрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рд╕рднреА рдХрд╛ рдзрдиреНрдпрд╡рд╛рдж рдФрд░ рдЬрд▓реНрдж рд╣реА рдЖрдкрдХреЛ рджреЗрдЦреВрдВрдЧрд╛ред

Source: https://habr.com/ru/post/hi471026/


All Articles