JSX рд╕реЗ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЯрд╛рдЗрдк рдбреАрдПрд╕рдПрд▓


рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ JSX рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд╕рдорд░реНрдерди рд╣реИ рдФрд░ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрдВрдкрд╛рдЗрд▓рд░ JSX рд╕рдВрдХрд▓рди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рдЙрдкрдХрд░рдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ, рдпрд╣ JSX рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП DSL рд▓рд┐рдЦрдирд╛ рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИред рдпрд╣ рдЖрд▓реЗрдЦ рдЗрд╕ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░реЗрдЧрд╛ - рдбреАрдПрд╕рдПрд▓ рдХреИрд╕реЗ рд▓рд┐рдЦреЗрдВ рдЖрд░ рд╕реЗ jsx рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред рд░реБрдЪрд┐, рдореИрдВ рдмрд┐рд▓реНрд▓реА рдХреЗ рд▓рд┐рдП рдкреВрдЫрдирд╛ред


тЖТ рдПрдХ рддреИрдпрд╛рд░ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рднрдВрдбрд╛рд░ред


рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рд╡реЗрдм, рд░рд┐рдПрдХреНрдЯ рдФрд░ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреЛ рдирд╣реАрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ред рд╡реЗрдм рд╕реЗ рдирд╣реАрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ рдХрд┐ JSX рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХреЛ рд░рд┐рдПрдХреНрдЯ, рдЗрд╕рдХреЗ рдШрдЯрдХреЛрдВ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдорд▓реЗ рдореЗрдВ HTML рдХреА рдкреАрдврд╝реА рддрдХ рд╕реАрдорд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рд╕реНрд▓реИрдХ рдХреЗ рд▓рд┐рдП рд╕рдВрджреЗрд╢ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбреАрдПрд╕рдПрд▓ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПред


рдпрд╣рд╛рдВ рд╡рд╣ рдХреЛрдб рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддреЗ рд╣реИрдВред рдпрд╣ рдЙрд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдПрдХ рдЫреЛрдЯрд╛ рд╕рдВрджреЗрд╢ рдХрд╛рд░рдЦрд╛рдирд╛ рд╣реИ:


interface Story { title: string link: string publishedAt: Date author: { name: string, avatarURL: string } } const template = (username: string, stories: Story[]) => ({ text: `:wave:  ${username},    .`, attachments: stories.map(s => ({ title, color: '#000000', title_link: s.link, author_name: s.author.name, author_icon: s.author.avatarURL, text: `  _${s.publishedAt}_.` }) }) 

рдпрд╣ рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдмрд┐рдВрджреБ рд╣реИ рдЬрд┐рд╕реЗ рдХрд╛рдлреА рд╕реБрдзрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдкрдардиреАрдпрддрд╛ ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, title_link color рд╕рдВрдкрддреНрддрд┐ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ, рд╢реАрд░реНрд╖рдХ ( title рдФрд░ title_link ) рдХреЗ рд▓рд┐рдП рджреЛ рдлрд╝реАрд▓реНрдб, рдпрд╛ text рдореЗрдВ рдЕрдВрдбрд░рд╕реНрдХреЛрд░ ( _ рдЕрдВрджрд░ рдкрд╛рда title_link рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛)ред рдпрд╣ рд╕рдм рд╣рдореЗрдВ рд╢реИрд▓реАрдЧрдд рд╡рд┐рд╡рд░рдг рд╕реЗ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдФрд░ рдРрд╕реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд╕рд╛рде, рдбреАрдПрд╕рдПрд▓ рдХреЛ рдорджрдж рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред


рдпрд╣рд╛рдБ рдПрдХ рд╣реА рдЙрджрд╛рд╣рд░рдг JSX рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ:


 const template = (username: string, stories: Story[]) => <message> :wave:  ${username},    . {stories.map(s => <attachment color='#000000'> <author icon={s.author.avatarURL}>{s.author.name}</author> <title link={s.link}>{s.title}</title>   <i>{s.publishedAt}</i>. </attachment> )} </message> 

рдмрд╣реБрдд рдмреЗрд╣рддрд░! рд╕рдм рдХреБрдЫ рдЬреЛ рдПрдХ рд╕рд╛рде рд░рд╣рдирд╛ рдЪрд╛рд╣рд┐рдП рдПрдХрдЬреБрдЯ, рд╢реИрд▓реАрдЧрдд рд╡рд┐рд╡рд░рдг рдФрд░ рд╕рд╛рдордЧреНрд░реА рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрд▓рдЧ рд╣реЛ рдЧрдИ рд╣реИ - рдПрдХ рд╢рдмреНрдж рдореЗрдВ рд╕реМрдВрджрд░реНрдпред


рдПрдХ рдбреАрдПрд╕рдПрд▓ рд▓рд┐рдЦрдирд╛


рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░реЗрдВ


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ JSX рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рд╕рдВрдХрд▓рдХ рдХреЛ рдмрддрд╛рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рд╣рдо React рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ JSX рдХреЛ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


 // tsconfig.json { "compilerOptions": { "jsx": "react", "jsxFactory": "Template.create" } } 

"jsx": "react" рдореЗрдВ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ React.createElement рд╕рдорд░реНрдерди рд╢рд╛рдорд┐рд▓ рд╣реИ рдФрд░ рд╕рдВрдХрд▓рдХ рд╕рднреА React.createElement рддрддреНрд╡реЛрдВ рдХреЛ React.createElement рдХреЙрд▓ рдореЗрдВ React.createElement рдХрд░рддрд╛ рд╣реИред рдФрд░ "jsxFactory" рд╡рд┐рдХрд▓реНрдк "jsxFactory" рддрддреНрд╡реЛрдВ рдХреЗ рд╣рдорд╛рд░реЗ рдХрд╛рд░рдЦрд╛рдиреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдХрд▓рдХ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рддрд╛ рд╣реИред


рдЗрди рд╕рд░рд▓ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЗ рдмрд╛рдж, рдлреЙрд░реНрдо рдХрд╛ рдХреЛрдб:


 import * as Template from './template' const JSX = <message>Text with <i>italic</i>.</message> 

рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВрдЧреЗ


 const Template = require('./template'); const JSX = Template.create('message', null, 'Text with ', Template.create('i', null, 'italic'), '.'); 

JSX рдЯреИрдЧ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВ


рдЕрдм рдЬрдм рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдкрддрд╛ рд╣реИ рдХрд┐ JSX рдХреЛ рдХрд┐рд╕ рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдирд╛ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдЦреБрдж рд╣реА рдЯреИрдЧ рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рд╢рд╛рдВрдд рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ - рдЕрд░реНрдерд╛рддреН, рд╕реНрдерд╛рдиреАрдп рдирд╛рдо рд╕реНрдерд╛рди рдХреА рдШреЛрд╖рдгрд╛ред рдЬреЗрдПрд╕рдПрдХреНрд╕ рдХреЗ рд╕рд╛рде рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП, рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдЬреЗрдПрд╕рдПрдХреНрд╕ рдиреЗрдорд╕реНрдкреЗрд╕ (рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реНрдерд╛рди рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛) IntrinsicElements рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд╕рд╛рде рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЯреИрдЧ рд╕реНрд╡рдпрдВ рд╡рд░реНрдгрд┐рдд рд╣реИрдВред рдХрдВрдкрд╛рдЗрд▓рд░ рдЙрдиреНрд╣реЗрдВ рдкрдХрдбрд╝рддрд╛ рд╣реИ рдФрд░ рдЯрд╛рдЗрдк рдЪреЗрдХрд┐рдВрдЧ рдФрд░ рд╕рдВрдХреЗрдд рдХреЗ рд▓рд┐рдП рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред


 // jsx.d.ts declare namespace JSX { interface IntrinsicElements { i: {} message: {} author: { icon: string } title: { link?: string } attachment: { color?: string } } } 

рдпрд╣рд╛рдВ рд╣рдордиреЗ рд╣рдорд╛рд░реЗ DSL рдФрд░ рдЙрдирдХреЗ рд╕рднреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рднреА JSX рдЯреИрдЧ рдШреЛрд╖рд┐рдд рдХрд┐рдП рд╣реИрдВред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рдХреБрдВрдЬреА рдирд╛рдо рд╕реНрд╡рдпрдВ рдЯреИрдЧ рдХрд╛ рдирд╛рдо рд╣реИ, рдЬреЛ рдХреЛрдб рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реЛрдЧрд╛ред рдорд╛рди рдЙрдкрд▓рдмреНрдз рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╡рд░рдг рд╣реИред рдХреБрдЫ рдЯреИрдЧ (рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ) рдореЗрдВ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖рддрд╛ рдирд╣реАрдВ рд╣реИ, рдЕрдиреНрдп рд╡реИрдХрд▓реНрдкрд┐рдХ рдпрд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред


рдлреИрдХреНрдЯрд░реА рд╣реА - Template.create


tsconfig.json рд╕реЗ рд╣рдорд╛рд░рд╛ рдХрд╛рд░рдЦрд╛рдирд╛ рдмрд╛рддрдЪреАрдд рдХрд╛ рд╡рд┐рд╖рдп рд╣реИред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


рд╕рдмрд╕реЗ рд╕рд░рд▓ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:


 type Kinds = keyof JSX.IntrinsicElements //    type Attrubute<K extends Kinds> = JSX.IntrinsicElements[K] //    export const create = <K extends Kinds>(kind: K, attributes: Attrubute<K>, ...children) => { switch (kind) { case 'i': return `_${chidlren.join('')}_` default: // ... } } 

рдЯреИрдЧ рдЬреЛ рдХреЗрд╡рд▓ рдкрд╛рда рдХреЗ рдЕрдВрджрд░ рдХреА рд╢реИрд▓рд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рд▓рд┐рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИ ( i рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ): рд╣рдорд╛рд░рд╛ рдХрд╛рд░рдЦрд╛рдирд╛ рдХреЗрд╡рд▓ рдЯреИрдЧ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ _ рджреЛрдиреЛрдВ рддрд░рдл рд╕реЗ рд▓рдкреЗрдЯрддрд╛ рд╣реИред рд╕рдорд╕реНрдпрд╛рдПрдБ рдЬрдЯрд┐рд▓ рдЯреИрдЧ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИрдВред рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдордп рдореИрдВрдиреЗ рдЗрд╕реЗ рдЙрдирдХреЗ рд╕рд╛рде рдмрд┐рддрд╛рдпрд╛, рдПрдХ рдХреНрд▓реАрдирд░ рд╕рдорд╛рдзрд╛рди рдХреА рддрд▓рд╛рд╢ рдореЗрдВред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдорд╕реНрдпрд╛ рдХреНрдпрд╛ рд╣реИ?


рдФрд░ рдпрд╣ рд╣реИ рдХрд┐ рд╕рдВрдХрд▓рдХ <message>Text</message> any <message>Text</message> рдХреЛ рдкреНрд░рд┐рдВрдЯ рдХрд░рддрд╛ рд╣реИред рдЬреЛ рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рдбреАрдПрд╕рдПрд▓ рдХреЗ рд╕рд╛рде рдХрд░реАрдм рдирд╣реАрдВ рдЖрдпрд╛, рдареАрдХ рд╣реИ, рдареАрдХ рд╣реИ, рд╕рдорд╕реНрдпрд╛ рдХрд╛ рджреВрд╕рд░рд╛ рднрд╛рдЧ рдпрд╣ рд╣реИ рдХрд┐ рдХрд╛рд░рдЦрд╛рдиреЗ рд╕реЗ рдЧреБрдЬрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╕рднреА рдЯреИрдЧ рдХрд╛ рдкреНрд░рдХрд╛рд░ рдПрдХ рд╣реЛрдЧрд╛ - рдпрд╣ рд╕реНрд╡рдпрдВ рдЬреЗрдПрд╕рдПрдХреНрд╕ рдХреА рдПрдХ рд╕реАрдорд╛ рд╣реИ (рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рд╕рднреА рдЯреИрдЧ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рддреНрдордХ рд░реВрдк рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ)ред


рдкреАрдврд╝реА рдмрдЪрд╛рд╡ рдХреЗ рд▓рд┐рдП рдЬрд╛рдУ!


 // jsx.d.ts declare namespace JSX { interface Element { toMessage(): { text?: string attachments?: { text?: string author_name?: string author_icon?: string title_link?: string color?: string }[] } } interface IntrinsicElements { i: {} message: {} author: { icon: string } title: { link?: string } attachment: { color?: string } } } 

рдХреЗрд╡рд▓ Element рдЬреЛрдбрд╝рд╛ Element рдФрд░ рдЕрдм рдХрдВрдкрд╛рдЗрд▓рд░ рд╕рднреА JSX рдЯреИрдЧреНрд╕ рдХреЛ Element рдЯрд╛рдЗрдк рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХрд░реЗрдЧрд╛ред рдпрд╣ рднреА рдорд╛рдирдХ рд╕рдВрдХрд▓рдХ рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реИ - рд╕рднреА рдЯреИрдЧ рдХреЗ рд▓рд┐рдП JSX.Element рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред


рд╣рдорд╛рд░реЗ Element рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рдзрд┐ рд╣реИ - рдЗрд╕реЗ рд╕рдВрджреЗрд╢ рд╡рд╕реНрддреБ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдбрд╛рд▓рдирд╛ред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ рд╣рдореЗрд╢рд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рдХреЗрд╡рд▓ рд╢реАрд░реНрд╖-рд╕реНрддрд░реАрдп <message/> рдФрд░ рдпрд╣ рдЯрд╛рдЗрдо-рдЖрдЙрдЯ рдореЗрдВ рд╣реЛрдЧрд╛ред


рдФрд░ рдмрд┐рдЧрд╛рдбрд╝рдиреЗ рдХреЗ рддрд╣рдд рд╣рдорд╛рд░реЗ рдХрд╛рд░рдЦрд╛рдиреЗ рдХрд╛ рдкреВрд░рд╛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИред


рдлреИрдХреНрдЯреНрд░реА рдХреЛрдб рд╣реА
 import { flatten } from 'lodash' type Kinds = keyof JSX.IntrinsicElements //    type Attrubute<K extends Kinds> = JSX.IntrinsicElements[K] //    const isElement = (e: any): e is Element<any> => e && e.kind const is = <K extends Kinds>(k: K, e: string | Element<any>): e is Element<K> => isElement(e) && e.kind === k /*         () */ const buildText = (e: Element<any>) => e.children.filter(i => !isElement(i)).join('') const buildTitle = (e: Element<'title'>) => ({ title: buildText(e), title_link: e.attributes.link }) const buildAuthor = (e: Element<'author'>) => ({ author_name: buildText(e), author_icon: e.attributes.icon }) const buildAttachment = (e: Element<'attachment'>) => { const authorNode = e.children.find(i => is('author', i)) const author = authorNode ? buildAuthor(<Element<'author'>>authorNode) : {} const titleNode = e.children.find(i => is('title', i)) const title = titleNode ? buildTitle(<Element<'title'>>titleNode) : {} return { text: buildText(e), ...title, ...author, ...e.attributes } } class Element<K extends Kinds> { children: Array<string | Element<any>> constructor( public kind: K, public attributes: Attrubute<K>, children: Array<string | Element<any>> ) { this.children = flatten(children) } /* *          `<message/>` */ toMessage() { if (!is('message', this)) return {} const attachments = this.children.filter(i => is('attachment', i)).map(buildAttachment) return { attachments, text: buildText(this) } } } export const create = <K extends Kinds>(kind: K, attributes: Attrubute<K>, ...children) => { switch (kind) { case 'i': return `_${children.join('')}_` default: return new Element(kind, attributes, children) } } 

тЖТ рдПрдХ рддреИрдпрд╛рд░ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рднрдВрдбрд╛рд░ред


рдПрдХ рдирд┐рд╖реНрдХрд░реНрд╖ рдХреЗ рдмрдЬрд╛рдп


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

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


All Articles