рд╣рд╛рдп рд╣рдмрд░, рдЖрдЬ рд╣рдо рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рд░рд┐рдПрдХреНрдЯ-рд╣реБрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред рдпрд╣ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдЖрдкрдХреЛ "рд╕реНрдХреНрд░рд┐рдкреНрдЯ" рдХреА рдореВрд▓ рдмрд╛рддреЗрдВ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ рдФрд░ рдлреНрд░рдВрдЯ-рдПрдВрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдп рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред
рдкреНрд░реЛрдЬреЗрдХреНрдЯ "рд╡рд┐рджрд╛рдЙрдЯ рд╡реЙрдЯрд░" рдкрд░ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдп рдХреЛрдб-рд╕рдореАрдХреНрд╖рд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрд╡рд╕рд░ рд╣реИред рд╡рд░реНрддрдорд╛рди рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдХреА рдЕрдВрддрд┐рдо рддрд┐рдерд┐ 11 рдЕрдкреНрд░реИрд▓, 2019 рд╣реИред

рд╡реАрдбрд┐рдпреЛ рд╕рдВрд╕реНрдХрд░рдг
рдпрджрд┐ рдЖрдк рдкрдврд╝рдиреЗ рдореЗрдВ рдмрд╣реБрдд рдЖрд▓рд╕реА рд╣реИрдВ, рддреЛ 20 рдорд╛рд░реНрдЪ рдХреЛ 21:00 рдорд╛рд╕реНрдХреЛ рд╕рдордп рдкрд░ рд╡реЗрдмрд┐рдирд╛рд░ рдореЗрдВ рдЖрдПрдВред рдкрдВрдЬреАрдХрд░рдг (рдИ-рдореЗрд▓ рдФрд░ рдПрд╕рдПрдордПрд╕ рдХреЗ рдмрд┐рдирд╛)ред рд╡реЗрдмрд┐рдирд╛рд░ рдЖрдпреЛрдЬрд┐рдд, рд╡реЗрдмрд┐рдирд╛рд░ рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ ред
рдЯреНрд░реЗрдирд┐рдВрдЧ
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк Create-react-app рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рдВрд╕реНрдХрд░рдг рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдореЗрд░реЗ рд╕реНрдЯрд╛рд░реНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдЬрд┐рд╕рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рдкрд╣реБрдВрдЪ-рд░рд╛рдЙрдЯрд░ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ)
рдореИрдВ рдЕрдкрдиреЗ рд╕реНрдЯрд╛рд░реНрдЯрд░ ("рдЕрднреНрдпрд╛рд╕" рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ ред
рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдереНрдпреЛрд░реА
рдЯреАрдПрд╕ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ "рдЧрддрд┐рд╢реАрд▓ рдЯрд╛рдЗрдкрд┐рдВрдЧ" рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ, рдЬрдм рдЖрдкрдХрд╛ рдЪрд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдорд╛рди рд▓реЗ рд╕рдХрддрд╛ рд╣реИред рдЕрдм рдПрдХ рд░реЗрдЦрд╛, рдлрд┐рд░ рдПрдХ рд╕рдВрдЦреНрдпрд╛, рдпрд╛ рдПрдХ рд╡рд╕реНрддреБ рднреАред 19 рд╡реАрдВ рд╢рддрд╛рдмреНрджреА рдореЗрдВ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдерд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдм рд╣рд░ рдХреЛрдИ рдЗрд╕ рдмрд╛рдд рд╕реЗ рд╕рд╣рдордд рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдкреНрд░рдХрд╛рд░ (рдирд┐рдпрдореЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ) рд╣реИ, рддреЛ рдХреЛрдб рдЖрдзрд╛рд░ рдмрдирд╛рдП рд░рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИред рдФрд░ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╕реНрддрд░ рдкрд░ рдХрдо рдХреАрдбрд╝реЗ рд╣реИрдВред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдШрдЯрдХ рд╣реИ рдЬреЛ рдПрдХ рд╕рдорд╛рдЪрд╛рд░ рдЖрдЗрдЯрдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╣рдо рд╕рдорд╛рдЪрд╛рд░ рдЖрдЗрдЯрдо рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдордиреЗ рдЕрдкрдиреЗ "рд╕рдорд╛рдЪрд╛рд░" рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЧреБрдгреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдЦреНрдд "рд╕реНрдерд┐рд░" рдкреНрд░рдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдП рд╣реИрдВред рдЕрдЧрд░ рд╣рдо рдПрдХ рднреАрдордХрд╛рдп рд╕рдВрдкрддреНрддрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдПрдХ рддреНрд░реБрдЯрд┐ рджрд┐рдЦрд╛рдПрдЧрд╛ред
import * as React from 'react' import { INewsItem } from '../models/news'

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡рд┐рдЬрд╝реБрдЕрд▓ рд╕реНрдЯреВрдбрд┐рдпреЛ рдХреЛрдб рдФрд░ рдЕрдиреНрдп рдЙрдиреНрдирдд рд╕рдВрдкрд╛рджрдХ рдЖрдкрдХреЛ рдПрдХ рддреНрд░реБрдЯрд┐ рджрд┐рдЦрд╛рдПрдВрдЧреЗ:

рджреГрд╖реНрдЯрд┐рдЧрдд, рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╡реАрдПрд╕ рдХреЛрдб рджреЛ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдПрдХ рд╕рд╛рде рджрд┐рдЦрд╛рддрд╛ рд╣реИ: рдЪрд░ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╕реЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдЕрд░реНрдерд╛рдд, рдпрд╣ рд╣рдорд╛рд░реЗ "рдЗрдВрдЯрд░рдлрд╝реЗрд╕" рд╕рдорд╛рдЪрд╛рд░ рдореЗрдВ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ) рдФрд░ "рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред" рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдкреНрд░рдпреБрдХреНрдд рдЪрд░ рдЬрдм рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╡реАрдПрд╕ рдХреЛрдб рдореЗрдВ рд╣рд▓реНрдХреЗ рд░рдВрдЧ рдореЗрдВ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред
рдпрд╣рд╛рдВ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рдирд╛ рд╕рд╛рд░реНрдердХ рд╣реИ рдХрд┐ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рд╡реАрдПрд╕ рдХреЛрдб рдХреЗ рдРрд╕реЗ рдШрдирд┐рд╖реНрда рдПрдХреАрдХрд░рдг рдХрд╛ рдХрд╛рд░рдг: рджреЛрдиреЛрдВ рдЙрддреНрдкрд╛рдж Microsoft рдХреЗ рд╡рд┐рдХрд╛рд╕ рд╣реИрдВред
рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╣рдореЗрдВ рдФрд░ рдХреНрдпрд╛ рдмрддрд╛ рд╕рдХрддрд╛ рд╣реИ? рдЪрд░ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдмреЛрд▓рддреЗ рд╣реБрдП, рдпрд╣ рдмрд╛рдд рд╣реИред рдЯреАрдПрд╕ рдмрд╣реБрдд рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╣реИ, рд╡рд╣ рд╕рдордЭрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣реИред
const NewsItem: React.FC<INewsItemProps> = ({ data: { id, title, text } }) => { return ( <article> <div>{id.toUpperCase()}</div> {/* , , 'number' toUpperCase() */} <div>{title.toUpperCase()}</div> {/* ! */} <div>{text}</div> </article> ) }

рдпрд╣рд╛рдБ, рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рддреБрд░рдВрдд рдПрдХ number
рдХреА рд╕рдВрдкрддреНрддрд┐ рдкрд░ рд╢рдкрде рд▓реЗрддрд╛ рд╣реИ - рдЯрд╛рдЗрдк number
рдХрд╛ рдЯреЙрдкрд░рдХреЗрд╕ред рдФрд░ рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдХреЗрд╡рд▓ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рдЯреЙрдкрд░ рдХреИрд╕ () рд╡рд┐рдзрд┐рдпрд╛рдВ рд╣реИрдВред
рдЕрдм рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ, рдЖрдк рдХреБрдЫ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдирд╛рдо рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдмреНрд░реИрдХреЗрдЯ рдЦреЛрд▓реЗрдВ рдФрд░ рд╕рдВрдкрд╛рджрдХ рддреБрд░рдВрдд рдЖрдкрдХреЛ рдПрдХ рдкреЙрдк-рдЕрдк рдорджрдж рд╡рд┐рдВрдбреЛ рджрд┐рдЦрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд┐рд╕ рддрд░реНрдХ рдФрд░ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдпрд╛ рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ - рдЖрдкрдиреЗ рдХрдбрд╝рд╛рдИ рд╕реЗ рд╕рд┐рдлрд╛рд░рд┐рд╢реЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд┐рдпрд╛ рдФрд░ рдЖрдкрдХреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкрд░ рдЯрд╛рдЗрдк рдХрд░рдирд╛ рдмреБрд▓реЗрдЯрдкреНрд░реВрдл рд╣реИред рдСрдЯреЛ-рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдкрдХреЛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд░ рдирд┐рд╣рд┐рдд ( undefined
) рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдорд┐рд▓рддрд╛ рд╣реИред
рдЕрднреНрдпрд╛рд╕
рд╣рдо рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд╣реБрдХ + рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд░ рдкрд╣рд▓реЗ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдп рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдЕрднреА рдХреЗ рд▓рд┐рдП, рдЪрд▓реЛ Redux рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВ, рдЕрдиреНрдпрдерд╛ " рдкреБрдирд░рд╛рд░рдВрдн рдХрд┐рдП рдЧрдП TK # 1 " рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп , рдЖрдк рдмрд╕ рдпрд╣рд╛рдВ рд╕реЗ рд╕рдм рдХреБрдЫ рдХреЙрдкреА рдХрд░рддреЗ рд╣реИрдВред
рдЙрдкрдХрд░рдг
( рд╡реАрдПрд╕ рдХреЛрдб рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░рдиреЗ рд╡рд╛рд▓реЛрдВ рдХреЗ рд▓рд┐рдП)
рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЖрдкрдХреЛ TSLint рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред
рдмрдЪрдд рдХреЗ рд╕рдордп TSLint рддреНрд░реБрдЯрд┐ рдХреЛ рд╕реНрд╡рддрдГ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рдВрдкрд╛рджрдХ рд╕реЗрдЯрд┐рдВрдЧ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
рдЖрдк рдореЗрдиреВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдореЗрдВ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдЖрдкрдХреЗ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рд╢рд╛рд░реАрд░рд┐рдХ рд░реВрдк рд╕реЗ рдХрд╣рд╛рдВ рд░рд╣рддреЗ рд╣реИрдВ ред
TSLint рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдорд╛рдирдХ рд╣реИрдВ, рд╕рд╛рде рд╣реА рдореИрдВрдиреЗ рдПрдХ рдирд┐рдпрдо рдХреЛ рдЕрдХреНрд╖рдо рдХрд░ рджрд┐рдпрд╛ рд╣реИред
{ "extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"], "linterOptions": { "exclude": [ "node_modules/**/*.ts", "src/serviceWorker.js" ] }, "rules": { "object-literal-sort-keys": false
рдПрдХреАрдХрд░рдг рдЦрддреНрдо рд╣реЛ рдЧрдпрд╛ рд╣реИ!
рд╣рдо рдПрдХ рдЖрд╡реЗрджрди рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ
рд╣рдо рдирд╛рдЯрдХ рдХреЗ рджреМрд░рд╛рди рд╣реА рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдирдИ рдЪреАрдЬреЛрдВ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реЛ рдЬрд╛рдПрдВрдЧреЗред рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдкрдиреА 1-рд╕реНрдЯрд╛рд░реНрдЯ рд╢рд╛рдЦрд╛ рдХреЛ рдХреНрд▓реЛрди рдХрд░реЗрдВ рдпрд╛ рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ рдореЗрд░реЗ рдХреЛрдб рдХреЗ рд╕рд╛рде рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░реЗрдВред
рд╕рднреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рдХрд╛рд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдлрд╝рд╛рдЗрд▓реЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди .tsx рд╣реИ ред
рд╢реБрд░реБрдЖрддреА рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдХреНрдпрд╛ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ?
- рдкреНрд░реА-рдХрдорд┐рдЯ рд╣реБрдХ (рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рдЗрд╕ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреА: рдкрд╛рда , рд╡реАрдбрд┐рдпреЛ )
- TSLint ( ESLint рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди)
- рдЗрд╕ рдФрд░ рдЕрдЧрд▓реЗ рдХрджрдо рдХреЗ рд▓рд┐рдП рд╢реБрд░реВ рдХрд░рдиреЗ рдФрд░ рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рд▓рд┐рдП рдлрд╝рд╛рдЗрд▓реЗрдВ
рдЖрдЗрдП src / App.tsx рдХреЗ рд╕рд╛рде рдЖрд░рдВрдн рдХрд░реЗрдВ:
import * as React from 'react' import './App.css' const App = () => { return ( <div className="container"> <h1>TZ #1 with hooks & TypeScript</h1> <nav> <p></p> </nav> <p> </p> </div> ) } const RoutedApp = () => { return <App /> } export { RoutedApp }

рдареАрдХ рд╣реИ, рдорд╛рдирдХ рд╢реБрд░реБрдЖрддред рдЖрдЗрдП <App />
рдХреБрдЫ рд╕рдВрдкрддреНрддрд┐ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ
src / App.tsx
const App = props => { return ( <div className="container"> <h1>TZ #1 with hooks & TypeScript</h1> <nav> <p></p> </nav> <p> </p> {/* name props */} <p>, {props.name}</p> </div> ) } // name const RoutedApp = () => { return <App name="Max Frontend" /> }
рд╣рдореЗрдВ рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИ:

(рдпрджрд┐ рдЖрдкрдХреЛ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рдорд┐рд▓реА рд╣реИ, рддреЛ рдЕрдкрдиреА tsconfig.json рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреА рдХрдареЛрд░рддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВ, рдПрдХ noImplicitAny рдирд┐рдпрдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП)
рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рддреНрд░реБрдЯрд┐ рдкрд╛рда рдХреЗ рдЕрдиреБрд╡рд╛рдж рд╕реЗ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдЧреБрдг рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдирд╣реАрдВ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрд╡рд╛рдж "рдХреБрдЫ рднреА" рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдПрдХ рдирд┐рдпрдо рд╣реИ рдЬреЛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдирд┐рд╣рд┐рдд рдЙрддреНрдкрд╛рджрди рдХреЛ рд░реЛрдХрддрд╛ рд╣реИред
- рдирд┐рд╣рд┐рдд рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди?
- рдмрд┐рд▓реНрдХреБрд▓! рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рдЪрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдХрдо рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИ рдФрд░ рдпрд╣ рдЗрд╕ рдХреБрдПрдВ рд╕реЗ рдореБрдХрд╛рдмрд▓рд╛ рдХрд░рддрд╛ рд╣реИред рдЗрд╕реЗ Type Inference рдХрд╣рддреЗ рд╣реИрдВ ред
рдПрдХ рдЙрджрд╛рд╣рд░рдг:
let x = 3
props
рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ - рдЯреАрдПрд╕ 100% рддрдХ рдЪрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЗрд╕рд▓рд┐рдП рдХрд╣рддрд╛ рд╣реИ - рдЗрд╕реЗ
рд╣реЛрдиреЗ рджреЗрдВ (рдЕрд░реНрдерд╛рдд рдЯрд╛рдЗрдк рдХрд░реЗрдВ)ред рдпрд╣ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд░реВрдк рд╕реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдпрд╣ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ (tsconfig.json) рдореЗрдВ noImplicitAny рдирд┐рдпрдо рджреНрд╡рд╛рд░рд╛ рдирд┐рд╖рд┐рджреНрдз рд╣реИред
рд╣рдо рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рддреНрд░реБрдЯрд┐ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рдПрдЧреАред рдЪрд░ рдХрд╛ рдкреНрд░рдХрд╛рд░ рдПрдХ рдмреГрд╣рджрд╛рдиреНрддреНрд░ рджреНрд╡рд╛рд░рд╛ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдХрд┐рдпрд╛, рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реИ, рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛рдо рдХрд░рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдРрд╕реЗ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХрд╛ рдХреНрдпрд╛ рдлрд╛рдпрджрд╛ рдЬрдм props
рдХреБрдЫ рднреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ? рд╣рдо рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░рд╛ рдирд╛рдо рдПрдХ
ред рдирд┐рдпрдо рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рд╕реЗ рдмрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ
рдРрд╕реЗ рд╕рдордп рд╣реЛрддреЗ рд╣реИрдВ рдЬрдм any
рдЖрд╡рд╢реНрдпрдХ any
рд╣реИ рдФрд░ рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рдЦреНрдд рдЯрд╛рдЗрдкрд┐рдВрдЧ рд╕реЗ рдпрд╣ рдХрдорд░ рд╕реЗ рдиреАрдЪреЗ рдПрдХ рдЭрдЯрдХрд╛ рд╣реИред
props
рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо interface
рдХреАрд╡рд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ:
name
рдкреНрд░рдХрд╛рд░ рдХреЛ number
рдмрджрд▓рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ рдФрд░ рдПрдХ рддреНрд░реБрдЯрд┐ рддреБрд░рдВрдд рд╣реЛ рдЬрд╛рдПрдЧреАред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡реАрдПрд╕ рдХреЛрдб (рдФрд░ рдХрдИ рдЕрдиреНрдп рд╕рдВрдкрд╛рджрдХреЛрдВ) рдореЗрдВ рднреА рддреНрд░реБрдЯрд┐ рдкрд░ рдЬреЛрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рддреНрд░реБрдЯрд┐ рдЗрдВрдЧрд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдореИрдЪ рдирд╣реАрдВ рд╣реИ: рд╣рдо рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдПрдХ рд╕рдВрдЦреНрдпрд╛ рдХреА рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВред
рд╣рдо props
рдФрд░ рдПрдХ рдФрд░ props
- рд╕рд╛рдЗрдЯ рдХреЛ <App />
рдЬреЛрдбрд╝ props
src / App.tsx
interface IAppProps { name: string; } const App = (props: IAppProps) => { return ( <div className="container"> <h1>TZ #1 with hooks & TypeScript</h1> <nav> <p></p> </nav> <p> </p> <p>, {props.name}</p> {/* site */} <p>: {props.site}</p> </div> ) } // site const RoutedApp = () => { return <App name="Max Frontend" site="maxpfrontend.ru" /> }
рдПрдХ рддреНрд░реБрдЯрд┐ рдорд┐рд▓реА:
Type error: Property 'site' does not exist on type 'IAppProps'. TS2339
site
рд╕рдВрдкрддреНрддрд┐ IAppProps
рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИред рдпрд╣рд╛рдВ, рдореИрдВ рддреБрд░рдВрдд рдХрд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЯрд╛рдЗрдк рдирд╛рдо рд╕реЗ рд╣рдо рддреБрд░рдВрдд рд╕рдордЭ рдЬрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдХрд╣рд╛рдВ рджреЗрдЦрдирд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдирд╛рдо рджреЗрдВред
рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рдЗрд╕реЗ рдареАрдХ рдХрд░ рджреЗрдВ, рдРрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВ: рдЙрд╕ рдЕрдиреБрдЪреНрдЫреЗрдж рдХреЛ рд╣рдЯрд╛ рджреЗрдВ рдЬреЛ props.site
ред
рд╣рдореЗрдВ рдПрдХ рдФрд░ рддреНрд░реБрдЯрд┐ рдкрд╛рда рдорд┐рд▓рддрд╛ рд╣реИ:

рдпрд╣рд╛рдВ рдореИрдВ рдХреЗрд╡рд▓ рд╡рд╣реА рдиреЛрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬреЛ рдЯреАрдПрд╕ рдиреЗ рдХрдЯреМрддреА рдХреА рдереА: site
рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ string
(рдпрд╣ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдореЗрдВ рд░реЗрдЦрд╛рдВрдХрд┐рдд рд╣реИ)ред
рдареАрдХ:
interface IAppProps { name: string; site: string;
рдХреЛрдИ рдЧрд▓рддреА рдирд╣реАрдВ, рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВред
рд░реВрдЯрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдмрдЪреНрдЪреЛрдВ рдХреЗ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЪрд▓реЛ рдЦреБрдж рд╕реЗ рдЖрдЧреЗ рдирд┐рдХрд▓рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ "рдмрд╛рд▓ рдШрдЯрдХ" рдЦреАрдВрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВред
const App = (props: IAppProps) => { return ( <div className="container"> <h1>TZ #1 with hooks & TypeScript</h1> ... // <p>: {props.site}</p> {props.children} </div> ) } const Baby = () => { return <p> </p> } const RoutedApp = () => { return ( <App name="Max Frontend" site="maxpfrontend.ru"> <Baby /> </App> ) }
рдЯреАрдПрд╕ рд╢рдкрде рд▓реЗрддреЗ рд╣реИрдВ, рд╡реЗ рдРрд╕рд╛ рдХрд╣рддреЗ children
- children
IAppProps
рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдмреЗрд╢рдХ, рд╣рдо рдХреБрдЫ рдорд╛рдирдХ рдЪреАрдЬреЛрдВ рдХреЛ "рдЯрд╛рдЗрдк" рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣рд╛рдВ рд╕рдореБрджрд╛рдп рдмрдЪрд╛рд╡ рдХреЗ рд▓рд┐рдП рдЖрддрд╛ рд╣реИ, рдЬреЛ рд╣рдорд╛рд░реЗ рд╕рд╛рдордиреЗ рдмрд╣реБрдд рдкрд╣рд▓реЗ рд╣реА рдЯрд╛рдЗрдк рдХрд░ рдЪреБрдХрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, @ рдкреНрд░рдХрд╛рд░ / рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреИрдХреЗрдЬ рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рд╕рднреА рдкреНрд░рдХрд╛рд░ рд╣реИрдВред
рдЗрд╕ рдкреИрдХреЗрдЬ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдХреЗ (рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реНрдерд╛рдкрд┐рдд рд╣реИ), рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
React.FunctionComponent<P> React.FC<P>
рдЬрд╣рд╛рдВ <P>
рд╣рдорд╛рд░реЗ props
рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рд╣реИрдВ, рдЕрд░реНрдерд╛рдд, рд░рд┐рдХреЙрд░реНрдб рдлреЙрд░реНрдо рд▓реЗрдЧрд╛ред
React.FC<IAppProps>
рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдЕрднреНрдпрд╛рд╕ рдХреЗ рдмрдбрд╝реЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рд╢реМрдХреАрди рд╣реИрдВ, рдЕрднреНрдпрд╛рд╕ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ " рдЬреЗрдирд░рд┐рдХ " (рдЙрди <рдФрд░>) рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд▓реЗрдЦ рдкреНрд░рд╕реНрддреБрдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рдмрд╛рдХреА рдХреЗ рд▓рд┐рдП, рдЕрднреА рдХреЗ рд▓рд┐рдП, рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдХрд┐ рд╣рдо рдЗрд╕ рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдХреЛ рдЗрд╕ рддрд░рд╣ рдЕрдиреБрд╡рд╛рдж рдХрд░рддреЗ рд╣реИрдВ: рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдШрдЯрдХ рдЬреЛ рдЗрд╕ рддрд░рд╣ рдХреЗ <- рдФрд░ - рдРрд╕реЗ рдЧреБрдгреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ>ред
рдРрдк рдШрдЯрдХ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдереЛрдбрд╝рд╛ рдмрджрд▓ рдЬрд╛рдПрдЧреАред рдкреВрд░реНрдг рд╕рдВрд╕реНрдХрд░рдгред
src / App.tsx
// , // React React.XXX, // XXX - import * as React from 'react' // , , // @types/react // interface IAppProps { name: string; site: string; } // const App: React.FC<IAppProps> = props => { return ( <div className="container"> <h1>TZ #1 with hooks & TypeScript</h1> <nav> <p></p> </nav> <p> </p> <p>, {props.name}</p> <p>: {props.site}</p> {props.children} </div> ) } const Baby = () => { return <p> </p> } const RoutedApp = () => { return ( <App name="Max Frontend" site="maxpfrontend.ru"> <Baby /> </App> ) }
рдЖрдЗрдП рдирд┐рдореНрди рд╡рд░реНрдгреЛрдВ рдХреЛ рдкрдВрдХреНрддрд┐рдмрджреНрдз рдХрд░реЗрдВ:
const App: React.FC<IAppProps> = props => {
- props
рдмрд╛рдж рдЯрд╛рдЗрдк рдХреНрдпреЛрдВ рдЧрд╛рдпрдм рд╣реЛ рдЧрдпрд╛?
- рдХреНрдпреЛрдВрдХрд┐, App
рдмрд╛рдж - рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ред
рд╣рдордиреЗ рджрд░реНрдЬ рдХрд┐рдпрд╛ рдХрд┐ рдРрдк рд╡реИрд░рд┐рдПрдмрд▓ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реЛрдЧрд╛: React.FC<IAppProps>
ред
React.FC
"рдлрд╝рдВрдХреНрд╢рди" рдХрд╛ рдПрдХ рдкреНрд░рдХрд╛рд░ рд╣реИ, рдФрд░ рдЕрдВрджрд░ <> рд╣рдордиреЗ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ рдХрд┐ рдпрд╣ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рддрд░реНрдХ рд▓реЗрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд, рд╣рдордиреЗ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ рдХрд┐ рд╣рдорд╛рд░рд╛ props
IAppProps
рдкреНрд░рдХрд╛рд░ рдХрд╛ IAppProps
ред
(рдПрдХ рдЬреЛрдЦрд┐рдо рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЖрдкрд╕реЗ рдХреБрдЫ рд╢рдмреНрджреЛрдВ рдореЗрдВ рдЭреВрда рдмреЛрд▓рд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЙрджрд╛рд╣рд░рдг рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдареАрдХ рд╣реИ)
рдХреБрд▓: рд╣рдордиреЗ рд╕рдВрдЪрд░рд┐рдд props
рд▓рд┐рдП рдЧреБрдгреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╕реАрдЦрд╛, рдЬрдмрдХрд┐ рд░рд┐рдПрдХреНрдЯ-рдШрдЯрдХреЛрдВ рдХреЗ "рдЙрдирдХреЗ" рдЧреБрдгреЛрдВ рдХреЛ рдирд╣реАрдВ рдЦреЛрдирд╛ред
рдлрд┐рд▓рд╣рд╛рд▓ рд╕реЛрд░реНрд╕ рдХреЛрдб ред
рд░реВрдЯрд┐рдВрдЧ рдЬреЛрдбрд╝реЗрдВ
рд╣рдо рдЕрдкрдиреЗ рдХреНрд╖рд┐рддрд┐рдЬ рдХреЛ рд╡реНрдпрд╛рдкрдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣реБрдВрдЪ-рд░рд╛рдЙрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдпрд╣ рдкреИрдХреЗрдЬ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд░рд╛рдЙрдЯрд░ рдХреЗ рд╕рдорд╛рди рд╣реИред
рдкреГрд╖реНрда рдЬреЛрдбрд╝реЗрдВ - рд╕рдорд╛рдЪрд╛рд░ (рд╕рдорд╛рдЪрд╛рд░), <App />
рдХреЛ рд╕рд╛рдлрд╝ рдХрд░реЗрдВред
src / Pages / News.tsx
import * as React from 'react' const News = () => { return ( <div className="news"> <p></p> </div> ) } export { News }
src / App.tsx
import * as React from 'react'
рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдЯреВрдЯ рдЧрдпрд╛ рд╣реИ, рдПрдХ рддреНрд░реБрдЯрд┐ (рддреНрд░реБрдЯрд┐рдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЯрд░реНрдорд┐рдирд▓ рдкрд╣рд▓реЗ рдПрдХ рдХреЛ рджрд┐рдЦрд╛рддрд╛ рд╣реИ):

рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рд╣рдо рдЗрд╕реЗ рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ path
<App />
рд▓рд┐рдП рд╡рд┐рд╡рд░рдг рдореЗрдВ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИред
рдлрд┐рд░, рд╣рдорд╛рд░реЗ рд╕рд╛рдордиреЗ рд╕рдм рдХреБрдЫ рд╡рд░реНрдгрд┐рдд рд╣реИред рд╣рдо @ рдЯрд╛рдЗрдк / рддрдХ рдкрд╣реБрдВрдЪ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ рдкреИрдХреЗрдЬ рдФрд░ RouteComponentProps
рдкреНрд░рдХрд╛рд░ред рдЕрдкрдиреЗ рдЧреБрдгреЛрдВ рдХреЛ рди рдЦреЛрдиреЗ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо extends
рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
import * as React from 'react'
рдЬрд┐рдЬреНрдЮрд╛рд╕реБ рдХреЗ рд▓рд┐рдП, RouteComponentProps рдореЗрдВ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ред
<App />
рдореЗрдВ рддреНрд░реБрдЯрд┐ рдЧрд╛рдпрдм рд╣реЛ рдЧрдИ, рд▓реЗрдХрд┐рди <News />
рдореЗрдВ рдмрдиреА рд░рд╣реА, рдХреНрдпреЛрдВрдХрд┐ рд╣рдордиреЗ рдЗрд╕ рдШрдЯрдХ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдкрд┐рдВрдЧ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХреА рдереАред
рдорд┐рдиреА рдкрд╣реЗрд▓реА: <News />
рд▓рд┐рдП рдЯрд╛рдЗрдкрд┐рдВрдЧ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВред рдлрд┐рд▓рд╣рд╛рд▓, рд░рд╛рдЙрдЯрд░ рд╕реЗ рдХреЗрд╡рд▓ рдЧреБрдгреЛрдВ рдХреЛ рд╡рд╣рд╛рдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЙрддреНрддрд░ рд╣реИ:
src / Pages / News.tsx
import * as React from 'react' import { RouteComponentProps } from '@reach/router'

рд╣рдо рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдорд╛рд░реНрдЧ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдкрд╣реБрдВрдЪ-рд░рд╛рдЙрдЯрд░ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реАрдзреЗ рдкреНрд░реЙрдкреНрд╕ рдореЗрдВ рд░рд╣рддреЗ рд╣реИрдВред рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд░рд╛рдЙрдЯрд░ рдореЗрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдХреЛ рдпрд╛рдж рд╣реИ, рд╡реЗ props.match
рдореЗрдВ рд░рд╣рддреЗ рд╣реИрдВред
src / App.tsx
import * as React from 'react' import { Link, RouteComponentProps, Router } from '@reach/router' import { About } from './pages/About' import { News } from './pages/News'
src / Pages / About.tsx
import * as React from 'react' import { RouteComponentProps } from '@reach/router' const About: React.FC<RouteComponentProps> = props => { return ( <div className="about"> <p> about</p> {/* source */} <p>{props.source}</p> </div> ) } export { About }
рдПрдХ рддреНрд░реБрдЯрд┐ рдЬрд┐рд╕рдХреА рд╣рдореЗрдВ рдЙрдореНрдореАрдж рдирд╣реАрдВ рдереА:

рд╕реНрд░реЛрдд рд╕рдВрдкрддреНрддрд┐ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ ... рдПрдХ рддрд░рдл, рдШрдмрд░рд╛рд╣рдЯ: рд╣рдо рдЗрд╕реЗ рдкрде рдкрд░ рднреЗрдЬрддреЗ рд╣реИрдВ, рдЬреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИ, рджреВрд╕рд░реА рдУрд░, рдЦреБрд╢реА: рдЖрд╣, рдареАрдХ рд╣реИ, рдХреИрд╕реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд▓реЗрдЦрдХ рдФрд░ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдиреЗ рдЗрд╕ рдЪреЗрддрд╛рд╡рдиреА рдХреЛ рд╣рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред
рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╡рд┐рдХрд▓реНрдкреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ: RouteComponentProps
рд╕реЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░реЗрдВ рдФрд░ рд╡реИрдХрд▓реНрдкрд┐рдХ source
рдЧреБрдг рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВред рд╡реИрдХрд▓реНрдкрд┐рдХ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╣рдорд╛рд░реЗ URL рдореЗрдВ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рд╢реНрди рдЪрд┐рд╣реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
src / Pages / About.tsx
import * as React from 'react' import { RouteComponentProps } from '@reach/router' interface IAboutProps extends RouteComponentProps { source?: string;
src / App.tsx (рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рд╣рдо рдиреЗрд╡рд┐рдЧреЗрд╢рди рдХреЛ рд╕рдВрддреБрд▓рд┐рдд рдХрд░реЗрдВрдЧреЗ)
import * as React from 'react' import { Link, RouteComponentProps, Router } from '@reach/router' import { About } from './pages/About' import { News } from './pages/News' import './App.css' interface IAppProps extends RouteComponentProps { name: string; site: string; } const App: React.FC<IAppProps> = props => { return ( <div className="container"> <h1>TZ #1 with hooks & TypeScript</h1> <nav> <Link to="/"></Link> <Link to="news"></Link>{' '} <Link to="/about/habr"> habr</Link>{' '} </nav> <hr /> <p> {' '} : {props.name} | : {props.site} </p> <hr /> {props.children} </div> ) } const RoutedApp = () => { return ( <Router> <App path="/" name="Max Frontend" site="maxpfrontend.ru"> <News path="/news" /> <About path="/about/:source" /> </App> </Router> ) } export { RoutedApp }

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

рд╕рдорд╛рдЪрд╛рд░ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ
рд╕рдорд╛рдЪрд╛рд░ рд╡рд╕реНрддреБрдУрдВ рдХреА рдПрдХ рд╕рд░рдгреА рд╣реИред
рдкреНрд░рд╕реНрддреБрдд рд╣реИ рд╣рдорд╛рд░реА рдЦрдмрд░:
{ id: 1, title: ' CRUD React-hooks', text: ' CRUD- ', link: 'https://maxpfrontend.ru/perevody/delaem-crud-prilozhenie-s-pomoschyu-react-hooks/', timestamp: new Date('01-15-2019'), },
рдЖрдЗрдП рдПрдХ рдореЙрдбрд▓ рддреБрд░рдВрдд рд▓рд┐рдЦреЗрдВ (рд╕рдорд╛рдЪрд╛рд░ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░):
src / рдореЙрдбрд▓ / news.ts ( .ts рдПрдХреНрд╕рдЯреЗрдВрд╢рди)
export interface INewsItem { id: number; title: string; text: string; link: string; timestamp: Date; }
рдирдП рд╕реЗ - рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк рдиреЗ Date
рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ред
рд╣рдорд╛рд░реЗ рдбреЗрдЯрд╛ рдХреЙрд▓ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ:
const fakeData = [ { id: 1, title: ' CRUD React-hooks', text: ' CRUD- ', link: 'https://maxpfrontend.ru/perevody/delaem-crud-prilozhenie-s-pomoschyu-react-hooks/', timestamp: new Date('01-15-2019'), }, { id: 2, title: ' React hooks', text: ' useState useEffect ', link: 'https://maxpfrontend.ru/perevody/znakomstvo-s-react-hooks/', timestamp: new Date('01-06-2019'), }, { id: 3, title: ' Google Sign In', text: ' Google Sign In ', link: 'https://maxpfrontend.ru/vebinary/avtorizatsiya-s-pomoschyu-google-sign-in/', timestamp: new Date('11-02-2018'), }, ] export const getNews = () => { const promise = new Promise(resolve => { resolve({ status: 200, data: fakeData,
рдПрдкреАрдЖрдИ рд╕реЗ рд╣рдорд╛рд░рд╛ рдХреЙрд▓ getNews
рд░рд┐рдЯрд░реНрди рдкреНрд░реЛрдорд┐рд╕ рд╣реИ , рдФрд░ рдЗрд╕ "рдкреНрд░реЙрдорд┐рд╕" рдореЗрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рдХрд╛рд░ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рд╣рдо рд╡рд░реНрдгрди рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
interface INewsResponse { status: number;
рдХреНрдпрд╛ рдпрд╣ рдЧрд░реНрдо рд╣реИ? рдЕрдм рдпрд╣ рдФрд░ рднреА рдЧрд░реНрдо рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╡рд╛рджрд╛ рдкреНрд░рдХрд╛рд░ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╣реИ, рд╣рдореЗрдВ рдлрд┐рд░ рд╕реЗ <
рдФрд░ >
рд╕реЗ рдирд┐рдкрдЯрдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХрд╛ рд╕рдмрд╕реЗ рдХрдард┐рди рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдордиреЗ рдЕрдВрддрд┐рдо рдХреЛрдб рдкрдврд╝рд╛:
src / api / News.ts
import { INewsItem } from '../models/news'
рдзреБрдЖрдВ рдЯреВрдЯрдирд╛ред
рдЦрдмрд░ рджрд┐рдЦрд╛рдУ
src / Pages / News.tsx
import * as React from 'react' import { RouteComponentProps } from '@reach/router' import { getNews } from '../api/news' import { NewsItem } from '../components/NewsItem'
рдХреЛрдб рдЯрд┐рдкреНрдкрдгреА рджреЗрддрд╛ рд╣реИ рдЬреЛ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд╣реБрдХ рдХреЗ рд╕рд╛рде рдорджрдж рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдк рдпрд╣рд╛рдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ: рдкреНрд░рд▓реЗрдЦрди (рдИрдПрди), рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ (рдЖрд░рдпреВ)ред
рдХрд╛рд░реНрдп: рдПрдХ <NewsItem />
рдШрдЯрдХ рд▓рд┐рдЦреЗрдВ рдЬреЛ рд╕рдорд╛рдЪрд╛рд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ред рд╕рд╣реА рдкреНрд░рдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рдпрд╛рдж рд░рдЦреЗрдВред INewsItem
рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
рдкрд░рд┐рдгрд╛рдо рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

рд╕рдорд╛рдзрд╛рди рдиреАрдЪреЗ рд╣реИред
src / Components / NewsItem.tsx
import * as React from 'react' import { INewsItem } from '../models/news' interface INewsItemProps { data: INewsItem;
рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдордиреЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ (рдХреЛрдб [1] рдФрд░ [2] рдореЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдВ)ред рдХреНрдпрд╛ рд╣рдо рд╕рд┐рд░реНрдл рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:
React.FC<INewsItem>
рдЬрд╡рд╛рдм рдиреАрдЪреЗ рд╣реИред
ред
ред
ред
рдЪреВрдВрдХрд┐, рд╣рдо data
рдкреНрд░реЙрдкрд░реНрдЯреА рдореЗрдВ рд╕рдорд╛рдЪрд╛рд░ рдкрд╛рд░рд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рдд рд╣рдореЗрдВ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛:
React.FC<{ data: INewsItem }>
рдЬреЛ рд╣рдордиреЗ рдХрд┐рдпрд╛, рдХреЗрд╡рд▓ рдЙрд╕ рдЕрдВрддрд░ рдХреЗ рд╕рд╛рде рдЬреЛ рд╣рдордиреЗ interface
рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдерд╛, рдпрджрд┐ рдШрдЯрдХ рдореЗрдВ рдЕрдиреНрдп рдЧреБрдг рдЬреЛрдбрд╝реЗ рдЧрдП рдереЗред рдФрд░ рдкрдардиреАрдпрддрд╛ рдмреЗрд╣рддрд░ рд╣реИред
рдХреБрд▓: рд╣рдордиреЗ рд╡рд╛рджрд╛ рдФрд░ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХрд╛ рдЕрднреНрдпрд╛рд╕ рдХрд┐рдпрд╛ред рдЕрдиреНрдп рдШрдЯрдХ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ред
рдпрджрд┐ рдЖрдк рдЕрднреА рднреА рдЯреАрдПрд╕ рдСрдЯреЛ-рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдФрд░ рд╕рдЦреНрддреА рд╕реЗ рдЕрдкрдиреЗ рд╣рд╛рдереЛрдВ рдХреЛ рддрд╛рд▓реА рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдпрд╛ рддреЛ рдЕрднреНрдпрд╛рд╕ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ рд╕рдЦреНрдд рдЯрд╛рдЗрдкрд┐рдВрдЧ рдЖрдкрдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рд╣реИред рджреВрд╕рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ - рдореИрдВ рдХреБрдЫ рднреА рдорджрдж рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛, рдпрд╣ рд╕реНрд╡рд╛рдж рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реИред рдореИрдВ рдЗрд╕ рддрдереНрдп рдкрд░ рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдмрд╛рдЬрд╛рд░ рдЕрдкрдиреА рд╢рд░реНрддреЛрдВ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рдЯрд╛рдЗрдкрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд░рд╣рддреА рд╣реИрдВ, рдпрджрд┐ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рд╣реИ, рддреЛ рдкреНрд░рд╡рд╛рд╣ рдХреЗ рд╕рд╛рдеред
рдлрд┐рд▓рд╣рд╛рд▓ рд╕реЛрд░реНрд╕ рдХреЛрдб ред
рдЕрдерд┐ рдЖрдкрд┐
рд▓реЙрдЧрд┐рди рдХреЗ рд▓рд┐рдП api
рд▓рд┐рдЦреЗрдВред рд╕рд┐рджреНрдзрд╛рдВрдд рд╕рдорд╛рди рд╣реИ - рд╣рдо рдЙрддреНрддрд░ рдЕрдзрд┐рдХреГрдд / рддреНрд░реБрдЯрд┐ рдХреЗ рд╕рд╛рде рдПрдХ promise
рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо localStorage
рдореЗрдВ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВрдЧреЗ ( рдХрдИ рдЗрд╕реЗ рд╕реБрд░рдХреНрд╖рд╛ рдХрд╛ рдПрдХ рдкреНрд░рдореБрдЦ рдЙрд▓реНрд▓рдВрдШрди рдорд╛рдирддреЗ рд╣реИрдВ, рдореИрдВ рд╡рд┐рд╡рд╛рджреЛрдВ рд╕реЗ рдереЛрдбрд╝рд╛ рдкреАрдЫреЗ рд╣реВрдВ рдФрд░ рдпрд╣ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рд╕рдорд╛рдкреНрдд рд╣реБрдЖ )ред
рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдореЗрдВ, рд▓реЙрдЧрд┐рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо рдФрд░ рдкрд╛рд╕рд╡рд░реНрдб рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рд╣реИ (рджреЛрдиреЛрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИрдВ), рд╣рдо рдореЙрдбрд▓ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВрдЧреЗ:
src / рдореЙрдбрд▓ / user.ts
export interface IUserIdentity { username: string; password: string; }
src / api / schem.ts
import { navigate } from '@reach/router' import { IUserIdentity } from '../models/user'
, .
:
: . useState . event
onChange
/ onSubmit
тАФ any
. .
React.useState
тАФ , ( React.useState<T>
)
, , , . , /profile
( navigate
)
.
ред
ред
ред
ред
src/pages/Login.tsx
import * as React from 'react' import { navigate, RouteComponentProps } from '@reach/router' import { authenticate } from '../api/auth' import { IUserIdentity } from '../models/user'
, TS тАФ . , , JavaScript.
: useState event
тЖТ
TypeScript' , .
, reach-router , react-router. , , , .
src/components/common/Authenticated.tsx
import * as React from 'react' import { Redirect, RouteComponentProps } from '@reach/router' import { checkAuthStatus } from '../../api/auth'
src/App.tsx
import * as React from 'react' import { Link, RouteComponentProps, Router } from '@reach/router' import { Authenticated } from './components/ommon/Authenticated' import { Home } from './pages/Home' import { Login } from './pages/Login' import { News } from './pages/News' import { Profile } from './pages/Profile' import { checkAuthStatus, logout } from './api/auth' import './App.css' const App: React.FC<RouteComponentProps> = props => { return ( <div className="container"> <h1>TZ #1 with hooks & TypeScript</h1> <nav> <Link to="/"></Link> <Link to="news"></Link>{' '} <Link to="profile"></Link>{' '} {checkAuthStatus() ? <button onClick={logout}></button> : null} </nav> {props.children} </div> ) } const RoutedApp = () => { return ( <Router> <App path="/"> <Home path="/" /> <Login path="/login" /> <News path="/news" /> <Authenticated path="/profile"> <Profile path="/" /> </Authenticated> </App> </Router> ) } export { RoutedApp }
.
. type="password"
.
, . "-", , , react-intl , react-i18next .
, . :
src/localization/formErrors.ts
const formErrors = { ru: { incorrect_login_or_password: ' ', }, en: { incorrect_login_or_password: 'Incorrect login or password', }, } export { formErrors }
<Login />
src/pages/Login.tsx
import * as React from 'react' import { navigate, RouteComponentProps } from '@reach/router' import { authenticate } from '../api/auth'
, .

TypeScript , , . , index signature ( , StackOverflow ).
interface IFormErrors { [key: string]: { [key: string]: string, }; } const formErrors: IFormErrors = { ru: { incorrect_login_or_password: ' ', }, en: { incorrect_login_or_password: 'Incorrect login or password', }, } export { formErrors }
, . , "".

тЖТ
рдирд┐рд╖реНрдХрд░реНрд╖
TypeScript. , TS . , , "one" "two" ( тАФ union).
, тАФ .
" " telegram youtube ( 11 2019).
рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж! , :

CRA + TypeScript
TypeScript Playground
тАФ Understanding TypeScript's type notation ( Dr.Axel Rauschmayer)
Microsoft,
TSLint
tslint
tslint
tsconfig.json tslint.json
d.ts .ts
, staging .
react-typescript-samples LemonCode
:
es5 (!)
React v16
typescript-.
Microsoft. UI- Fabric . , github .