рд░рд┐рдПрдХреНрдЯ рдХреЗ рд╕рд╛рде рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ - рдПрдХ рд╢реБрд░реБрдЖрддреА рдЧрд╛рдЗрдб

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



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

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

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

рдЖрдкрдХрд╛ рдХреЛрд░ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдШрдЯрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реИ


рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд░ рдорд╛рдирдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ? рдЖрдЗрдП рдЗрд╕рдХреА рддреБрд▓рдирд╛ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХ рдХреЗ рд╕рд╛рде рдХрд░реЗрдВред

import React from 'react' import PropTypes from 'prop-types' export function StandardComponent({ children, title = 'Dr.' }) { return ( <div> {title}: {children} </div> ) } StandardComponent.propTypes = { title: PropTypes.string, children: PropTypes.node.isRequired, } 

рдФрд░ рдЕрдм рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рдВрд╕реНрдХрд░рдг:

 import * as React from 'react' export interface StandardComponentProps { title?: string children: React.ReactNode } export function StandardComponent({ children, title = 'Dr.', }: StandardComponentProps) { return ( <div> {title}: {children} </div> ) } 

рдмрд╣реБрдд рд╕рдорд╛рди рд╣реИ, рд╣реИ рдирд╛? рд╣рдордиреЗ typescript рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде propTypes рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ред

prop рд╣реЗрдбрд░ рд╡реИрдХрд▓реНрдкрд┐рдХ рд░рд╣рддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рд╡рд╛рд░рд┐рд╕ рдХрд╛ рдкреНрд░реЛрдк рдЕрднреА рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдпрджрд┐ рдХрд┐рд╕реА рдЕрдиреНрдп рдШрдЯрдХ рдХреЛ рдЗрд╕рдХреЗ рд▓рд┐рдВрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рд╣рдордиреЗ рдЕрдкрдирд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдирд┐рд░реНрдпрд╛рдд рдХрд┐рдпрд╛ред

рдорд╛рдирдХ HTML рдЧреБрдг рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░


рдпрджрд┐ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдореВрд▓ рдШрдЯрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП div рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛ, рдЬреИрд╕реЗ рдХрд┐ aria-hidden , style рдпрд╛ className , рддреЛ рд╣рдо рдЙрдиреНрд╣реЗрдВ interface рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд interface рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░рд╛ рдШрдЯрдХ рд╣реЗрдбрд░ рдФрд░ рд╡рдВрд╢ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд┐рд╕реА рднреА рдорд╛рдирдХ div рдЧреБрдгреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред

 import * as React from 'react' export interface SpreadingExampleProps extends React.HTMLAttributes<HTMLDivElement> { title?: string children: React.ReactNode } export function SpreadingExample({ children, title = 'Dr.', ...other }: SpreadingExampleProps) { return ( <div {...other}> {title}: {children} </div> ) } 

рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд┐рдВрдЧ


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

 export interface EventHandlerProps { onClick: (e: React.MouseEvent) => void } export function EventHandler({ onClick }: EventHandlerProps) { // handle focus events in a separate function function onFocus(e: React.FocusEvent) { console.log('Focused!', e.currentTarget) } return ( <button onClick={onClick} onFocus={onFocus} onKeyDown={e => { // When using an inline function, the appropriate argument signature // is provided for us }} > Click me! </button> ) } 

рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХрд┐рд╕ рддрд░реНрдХ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ? рд╕рдВрдкрд╛рджрдХ рдореЗрдВ, рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреА рд╕рдВрдмрдВрдзрд┐рдд рд╕рдВрдкрддреНрддрд┐ рдкрд░ рд╣реЛрд╡рд░ рдХрд░реЗрдВред

рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХреЛрдВ рдХреЗ рд╕рд╛рде рдЬреЗрдирд░рд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рдпрд╣ рдПрдХ рдЕрдзрд┐рдХ рдЙрдиреНрдирдд рд╕реБрд╡рд┐рдзрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╣реИред рдЖрдорддреМрд░ рдкрд░, рдЖрдк рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХреЛрдВ рдореЗрдВ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдкрдХреЗ рдШрдЯрдХ рдХреЛ рдПрдХ profile рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

 interface ProfileType { name: string image: string age: number | null } interface ProfilesProps { profiles: Array<ProfileType> } function Profiles(props: ProfilesProps) { // render a set of profiles } 

рдЕрдм рдЖрдЗрдП рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдШрдЯрдХ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЬреЗрдирд░рд┐рдХ рдореЗрд▓рд┐рдВрдЧ рдкрд╛рд░реНрд╕рд▓ рдХреА рддрд░рд╣ рд╣реЛрддреЗ рд╣реИрдВред рдХреВрд░рд┐рдпрд░ (рд╣рдорд╛рд░реЗ рдШрдЯрдХ) рдХреЛ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рднреЗрдЬреЗ рдЬрд╛ рд░рд╣реЗ рдкреИрдХреЗрдЬ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдкреНрд░реЗрд╖рдХ (рдорд╛рддрд╛-рдкрд┐рддрд╛ рдШрдЯрдХ) рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рдХреЛ рдЙрд╕ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЙрд╕рдиреЗ рднреЗрдЬрд╛ рдерд╛ред

рд╣рдо рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ:

 interface GenericsExampleProps<T> { children: (item: T) => React.ReactNode items: Array<T> } export function GenericsExample<T>({ items, children, }: GenericsExampleProps<T>) { return ( <div> {items.map(item => { return children(item) })} </div> ) } 

рдереЛрдбрд╝рд╛ рдЕрдЬреАрдм рдЙрджрд╛рд╣рд░рдг ... рдлрд┐рд░ рднреА, рдпрд╣ рд╕рд╛рд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рдШрдЯрдХ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рддрддреНрд╡реЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╕рд░рдгреА рддрддреНрд╡ рдХреЗ рд╕рд╛рде children рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рд░реЗрдВрдбрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдмреБрд▓рд╛рддрд╛ рд╣реИред рдЬрдм рд╣рдорд╛рд░реЗ рдореВрд▓ рдШрдЯрдХ рдПрдХ рдЕрдиреБрд╡рд░реНрддреА рдХреЗ рд░реВрдк рдореЗрдВ рд░реЗрдВрдбрд░ рд░реЗрдВрдбрд░ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рддрддреНрд╡ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛!

рдирд╣реАрдВ рд╕рдордЭреЗ? рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп рд╣реИред рдореИрдВрдиреЗ рдЦреБрдж рднреА рдЬреЗрдиреЗрд░рд┐рдХ рдХреЛ рдЕрдВрдд рддрдХ рдирд╣реАрдВ рд╕рдордЭрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЙрдиреНрд╣реЗрдВ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрдк рдЬрд┐рддрдирд╛ рдЕрдзрд┐рдХ typescript рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ, рдЙрддрдирд╛ рд╣реА рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖрдПрдЧрд╛ред

рдЯрд╛рдЗрдкрд┐рдВрдЧ рд╣реБрдХ


рд╣реБрдХ рдЬреНрдпрд╛рджрд╛рддрд░ рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рджреЛ рдЕрдкрд╡рд╛рджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдХреИрд╕реЗ refs рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред

 import * as React from 'react' interface HooksExampleProps {} export function HooksExample(props: HooksExampleProps) { const [count, setCount] = React.useState(0) const ref = React.useRef<HTMLDivElement | null>(null) // start our timer React.useEffect( () => { const timer = setInterval(() => { setCount(count + 1) }, 1000) return () => clearTimeout(timer) }, [count] ) // measure our element React.useEffect( () => { if (ref.current) { console.log(ref.current.getBoundingClientRect()) } }, [ref] ) return <div ref={ref}>Count: {count}</div> } 

рд╣рдорд╛рд░рд╛ рд░рд╛рдЬреНрдп рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдордиреЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдпрд╣ рд╕рдВрдХреЗрдд рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ рдпрд╣ null рд╣реЛрдЧрд╛ рдпрд╛ рдЗрд╕рдореЗрдВ рдПрдХ div рддрддреНрд╡ рд╣реЛрдЧрд╛ред рдЬрдм рд╣рдо useEffect рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд░реЗрдл рдХреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ null рдирд╣реАрдВ рд╣реИред

рдЧрд┐рдпрд░рдмреЙрдХреНрд╕ рдЯрд╛рдЗрдкрд┐рдВрдЧ


рдЧрд┐рдпрд░рдмреЙрдХреНрд╕ рдХреЗ рд╕рд╛рде рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдпрд╣ рдареАрдХ рд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИред

 // Yeah, I don't understand this either. But it gives us nice typing // for our reducer actions. type Action<K, V = void> = V extends void ? { type: K } : { type: K } & V // our search response type interface Response { id: number title: string } // reducer actions. These are what you'll "dispatch" export type ActionType = | Action<'QUERY', { value: string }> | Action<'SEARCH', { value: Array<Response> }> // the form that our reducer state takes interface StateType { searchResponse: Array<Response> query: string } // our default state const initialState: StateType = { searchResponse: [], query: '', } // the actual reducer function reducer(state: StateType, action: ActionType) { switch (action.type) { case 'QUERY': return { ...state, query: action.value, } case 'SEARCH': return { ...state, searchResponse: action.value, } } } interface ReducerExampleProps { query: string } export function ReducerExample({ query }: ReducerExampleProps) { const [state, dispatch] = React.useReducer(reducer, initialState) React.useEffect( () => { if (query) { // emulate async query setTimeout(() => { dispatch({ type: 'SEARCH', value: [{ id: 1, title: 'Hello world' }], }) }, 1000) } }, [query] ) return state.searchResponse.map(response => ( <div key={response.id}>{response.title}</div> )) } 

рдХрдВрдкреЛрдиреЗрдВрдЯ рдСрдкреНрд╢рди рдХреЛ keyof рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП keyof рдФрд░ keyof рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


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

 const styles = { primary: { color: 'blue', }, danger: { color: 'red', }, } 

рд╣рдорд╛рд░реЗ рдмрдЯрди рдШрдЯрдХ рдХреЛ рдПрдХ type рд╕рдВрдкрддреНрддрд┐ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП, рдЬреЛ рд╣реЛ рд╕рдХрддреА рд╣реИ
styles рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реЗ рдХреЛрдИ рднреА рдХреБрдВрдЬреА (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, "рдкреНрд░рд╛рдердорд┐рдХ" рдпрд╛ "рдЦрддрд░реЗ" )ред рд╣рдо рдЗрд╕реЗ рдХрд╛рдлреА рд╕рд░рд▓рддрд╛ рд╕реЗ рдЯрд╛рдЗрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 const styles = { primary: { color: 'blue', }, danger: { color: 'red', }, } // creates a reusable type from the styles object type StylesType = typeof styles // ButtonType = any key in styles export type ButtonType = keyof StylesType interface ButtonProps { type: ButtonType } export function Button({ type = 'primary' }: ButtonProps) { return <button style={styles[type]}>My styled button</button> } 

рдпреЗ рдЙрджрд╛рд╣рд░рдг рдЖрдкрдХреЛ 80% рд░рд╛рд╕реНрддрд╛ рддрдп рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреЗред рдпрджрд┐ рдЖрдк рдлрдВрд╕ рдЧрдП рд╣реИрдВ, рддреЛ рдпрд╣ рдЕрдХреНрд╕рд░ рдпреЛрдЧреНрдп рд╣реИ
рдмрд╕ рдореМрдЬреВрджрд╛ рдЦреБрд▓реЗ рд╕реНрд░реЛрдд рдЙрджрд╛рд╣рд░рдгреЛрдВ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред

рд╕рд╛рдВрдЪреЛ рдпреВрдЖрдИ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдШрдЯрдХреЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИ,
рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рднрд╛рд╡рдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ред
рдмреНрд▓реВрдкреНрд░рд┐рдВрдЯ рдШрдЯрдХреЛрдВ рдХрд╛ рдПрдХ рдФрд░ рд╕реЗрдЯ рд╣реИ
typescript рдкрд░ рдирд┐рд░реНрдорд┐рдд react ред

рдЦреИрд░, рд╕реНрдерд╛рдкрд┐рдд рдкрд░рдВрдкрд░рд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рд╣рдо рдЖрдкрдХреА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВред

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


All Articles