{"id":373753,"date":"2024-05-21T05:43:28","date_gmt":"2024-05-21T05:43:28","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=373753"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=373753","title":{"rendered":"<span>\u0410 \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u0431\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u044f get \u0432 Lodash \u0432\u044b\u0432\u043e\u0434\u0438\u043b\u0430 \u0442\u0438\u043f\u044b \u0437\u0430 \u0432\u0430\u0441 \u0432 TypeScript<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! ?<\/p>\n<blockquote>\n<p>\u26a0\ufe0f \u0412\u043e\u0437\u0440\u043e\u0436\u0434\u0430\u044e \u0441\u0442\u0430\u0442\u044c\u044e, \u043c\u043d\u043e\u044e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u0443\u044e \u0432 2021 \u043d\u0430 \u0425\u0430\u0431\u0440\u0435. \u0418\u0437 \u043d\u043e\u0432\u043e\u0433\u043e &#8212; \u043f\u043e\u0434\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c, \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043a\u0443\u0441\u043a\u0438 \u043a\u043e\u0434\u0430, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0410\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0442\u0443\u0442 &#8212; <a href=\"https:\/\/blog.beraliv.dev\/2021-03-26-typed-get\" rel=\"noopener noreferrer nofollow\">https:\/\/blog.beraliv.dev\/2021-03-26-typed-get<\/a>. \u041f\u0440\u0438\u044f\u0442\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f ?<\/p>\n<\/blockquote>\n<pre><code class=\"typescript\">type Get&lt;O, P> = never; \/\/ \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c  type Step1 = Get&lt;   { article: { author: \"Alexey Berezin\"; keywords: [\"typescript\"] } },   \"article.keywords.0\" >; type Step2 = Get&lt;   { author: \"Alexey Berezin\"; keywords: [\"typescript\"] },   \"keywords.0\" >; type Step3 = Get&lt;[\"typescript\"], \"0\">; type Step4 = Get&lt;\"typescript\", \"\">; type Result = \"typescript\";<\/code><\/pre>\n<p>\u0412 2021 \u0433\u043e\u0434\u0443 \u044f \u0440\u0430\u0441\u043a\u043e\u043f\u0430\u043b \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u0430\u0445 GitHub \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439\u00a0<a href=\"https:\/\/github.com\/type-challenges\/type-challenges\" rel=\"noopener noreferrer nofollow\">type-challenges<\/a>. \u0423 \u043c\u0435\u043d\u044f \u0435\u0441\u0442\u044c \u0446\u0435\u043b\u044b\u0439 \u0431\u043b\u043e\u0433, \u0433\u0434\u0435 \u044f \u0440\u0435\u0448\u0430\u044e \u0437\u0430\u0434\u0430\u0447\u043a\u0438 \u043e\u0442\u0442\u0443\u0434\u0430, \u043d\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u043f\u043e\u043f\u044b\u0442\u0430\u044e\u0441\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e\u00a0<code>Get<\/code>, \u043d\u043e \u0438 \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e \u043e\u0431\u0449\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043f\u043e\u043a\u0430\u0436\u0443 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 production.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0447\u0442\u0435\u043d\u0438\u044f \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u043f\u043e\u043d\u044f\u0442\u0438\u044f\u043c\u0438 \u0438\u0437 TypeScript, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u0435 \u0432 \u043a\u043e\u043d\u0435\u0446.<\/p>\n<h3>1. \u0411\u0430\u0437\u043e\u0432\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h3>\n<p><a href=\"https:\/\/github.com\/type-challenges\/type-challenges\/blob\/main\/questions\/00270-hard-typed-get\/README.md\" rel=\"noopener noreferrer nofollow\">\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u0447\u0435\u043b\u043b\u0435\u043d\u0434\u0436<\/a>\u00a0\u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 &#171;\u0441\u043b\u043e\u0436\u043d\u043e\u0435&#187;.<\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u043f\u0443\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0435 (\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0443\u0442\u0438 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u0438\/\u0438\u043b\u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0435). \u041e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0442\u0438\u043f \u0432\u0435\u0440\u043d\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u0442\u0438\u043f \u043f\u043e \u043f\u0443\u0442\u0438 \u0432 \u044d\u0442\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0435.<\/p>\n<p>\u0422\u0430\u043a \u0441 \u0447\u0435\u0433\u043e \u0436\u0435 \u043d\u0430\u0447\u043d\u0435\u043c?<\/p>\n<h4>1.1. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u044e\u0447\u0435\u0439<\/h4>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0440\u0435\u0448\u0430\u043b\u0438 \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e JavaScript:<\/p>\n<pre><code class=\"javascript\">const get = (obj, path) => {   const keys = path.split(\".\");    return keys.reduce((currentObj, key) => currentObj[key], obj); };<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u00a0<code>keys.reduce<\/code>, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u043a\u043b\u044e\u0447\u0435\u0439. \u0412 JavaScript \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u00a0<code>split<\/code>. \u0412 TypeScript \u043d\u0430\u043c \u0442\u043e\u0436\u0435 \u043d\u0430\u0434\u043e \u043a\u0430\u043a-\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043b\u044e\u0447\u0435\u0439 \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f TypeScript 4.1, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u00a0<a href=\"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-4-1\/#template-literal-types\" rel=\"noopener noreferrer nofollow\">Template Literal types<\/a>. \u0421 \u0438\u0445 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0438 \u043c\u0435\u0436\u0434\u0443 \u043a\u043b\u044e\u0447\u0430\u043c\u0438. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0442\u0438\u043f\u00a0<code>Path<\/code>\u00a0\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434:<\/p>\n<pre><code class=\"typescript\">type Path&lt;T> = T extends `${infer Key}.${infer Rest}`   ? [Key, ...Path&lt;Rest>]   : [];<\/code><\/pre>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u043e\u0440\u043e\u0442\u043a\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043a\u0440\u044b\u0442\u0438\u044f \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u043c\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u0447\u0442\u043e \u0443\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u0441\u043b\u0443\u0447\u0430\u0439 \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c (\u0431\u0435\u0437 \u0442\u043e\u0447\u043a\u0438). \u0422\u0435\u0441\u0442\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0432\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBACghsAFgHgCoD4oF4qqhAD2AgDsATAZygAMASAbwEsSAzCAJygGkIQBfAHQNmbTgCUIFYH2oAoKFAD8UANo8QAGigCd8JMglT0AXXlQAXKtOyA9ACooAfWcvXL3JOBQAwnAqSnNyDHKDsbWUYAWzAAe3YveigAUQBHAFc4ABstJIJIAGMvPigWdhjIqAByAAFQSABafMQszNIAc0kbNOBGTIpK2Vk66Hy-AJwVM1yC4GRUjMzkPRRKmJIIeoBrXnqwBERK9C0VVfWtnb2kSuN0I6m8iEK59Kyl-eRKgCZzkAFLg6Oqi+P0qWkq-2utw09xmzwWb30lSQ7AgEAE21+EMBJ2RqNBVQx+PB+0hd2MQA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u043e\u0442 \u0441\u043b\u0443\u0447\u0430\u0439:<\/p>\n<pre><code class=\"typescript\">type Path&lt;T> = T extends `${infer Key}.${infer Rest}`   ? [Key, ...Path&lt;Rest>]   : T extends `${infer Key}`   ? [Key]   : [];<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043b\u0443\u0447\u0448\u0435. \u0422\u0435\u0441\u0442\u044b \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?ssl=5&amp;ssc=9&amp;pln=1&amp;pc=1#code\/C4TwDgpgBACghsAFgHgCoD4oF4qqhAD2AgDsATAZygAMASAbwEsSAzCAJygGkIQBfAHQNmbTgCUIFYH2oAoKFAD8UANo8QAGigCd8JMglT0AXXlQAXLnxFSlGsNYduvGWYXK1vUwoWWVp2QB6ACooAH0IyKjI3ElgKABhOApJcOj0sKhgwNlGAFswAHt2ePooAFEARwBXOAAbLXKCSABjeL4oFnZCvKgAcgABUEgAWhbEerrSAHNJQOrgRjqKPtlZYegW5NScFTMm1uBkKtq65D0UPsKSCBGAa14RsAREPvQtFSub+8fnpD7jOh3vtmhA2scavVzi9kH0AEw-EACP6vd6qeGIvpaPoogFAjQgw4Q07Q-R9JDsCAQAQPJG4tGfClUrH9WksnEvPHA4xAA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>.<\/p>\n<h4>1.2. Reducer \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043a\u043b\u044e\u0447\u0438, \u043c\u044b \u043d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c<code>keys.reduce<\/code>. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0442\u0438\u043f\u00a0<code>GetWithArray<\/code>\u00a0, \u0438\u043c\u0435\u044f \u0443\u0436\u0435 \u043f\u0443\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0430\u00a0<code>K<\/code><\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;O, K> = K extends [infer Key, ...infer Rest]   ? Key extends keyof O     ? GetWithArray&lt;O[Key], Rest>     : never   : never;<\/code><\/pre>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u044e:<\/p>\n<ol>\n<li>\n<p><code>K extends [infer Key, ...infer Rest]<\/code>\u00a0\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u043a\u043e\u0440\u0442\u0435\u0436\u0435<\/p>\n<\/li>\n<li>\n<p><code>Key extends keyof O<\/code>\u00a0\u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u00a0<code>O[Key]<\/code>\u00a0\u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0443\u0440\u043e\u0432\u043d\u044e \u043e\u0431\u044a\u0435\u043a\u0442\u0430<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u00a0(\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBA4hwHUCWwAWBBATpghiAPAPIA0UA0gHxQC85UEAHsBAHYAmAzlANpIsBmETOQghSAOkl9BwgEoQOwALoAoKFAD8IkPSatOUANaiA9vyiE16zbHjI0WXAULcyopaXmKKV9QC4oFggANyErAKDQzBUVAHoAKigAfRTUtNSoABUFYCgAYRwOBWT00qSoeNiVJABbMBNMXIBvKABRAEcAVxwAG1JWhkgAY1yAXyh+TBMaqAByAAFQSABaIdRentYAcwVYzuAkHo5ZmKXobMVCACMAKwgRmigmqwPgTYCAAwBlIamenquOGEQ06immSA4OAOJhYHysbChEE+ACYAAwARgAHMt0ajlqiACxw9Q4faoBoBZ7WQI4GpIqAfdCbBiiKAAISEEAAXnxidYeiYhlCkDDKb5rEMUCBPgBZTosJBrPnqUZWVWqlRnKBCopcWjcKwDYbAfAdbo9fBwRAoDDYPD4C7Aa53EakbizV6bWZKCikb6-Ez-QHA0HAcGQ6Gwii+w2De4ms29S12G2Oe2O53xt2zBHMb2+hlorE4vGEj7R4ix42mrpJq32W1OB05TOung5hS-JBgSP50iRIQVqvxmvm5PWhx2ggZ25Z9uktANWakWYsWkQPsMpmMVkczDc3lD9RGkeJi311NT5uXWdt90L8mYZdzAVC3sryWgTcfOUKpVHto4xGUc6xTScmxnF1gGzB8lw-IE2GfVdOhqK4hE3AdMCHJQgA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>). \u041e\u043f\u044f\u0442\u044c \u043c\u044b \u0437\u0430\u0431\u044b\u043b\u0438 \u0441\u043b\u0443\u0447\u0430\u0439, \u043f\u0440\u0430\u0432\u0434\u0430 \u0443\u0436\u0435 \u043a\u043e\u0433\u0434\u0430 \u0443 \u043d\u0430\u0441 \u043f\u0443\u0441\u0442\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432. \u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u0434 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;O, K> = K extends []   ? O   : K extends [infer Key, ...infer Rest]   ? Key extends keyof O     ? GetWithArray&lt;O[Key], Rest>     : never   : never;<\/code><\/pre>\n<p>\u0424\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0432<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBA4hwHUCWwAWBBATpghiAPAPIA0UA0gHxQC85UEAHsBAHYAmAzlANoC6AUFCgB+KIUFQAXHUbN2XbkhYAzCJnIQQpAHS6lq9QCUIHYAKFDRZTfSatOUANaaA9srESLI2PGRosuASE3NYgvKTGphSeFtIsEABuajFxicn8APQAVFAA+vkFhQVQAComwFAAwjgcJnlFDblQWRn8SAC2YC6YFQDeUACiAI4ArjgANqQDDJAAxhUAvlDKmC7tUADkAAKgkAC0s6gT46wA5iYZI8BI4xwb-Py70GWmhABGAFYQ8zRQvRLXYAnaQAAwAyrNVuNxm8cOpZiNTGskBwcNcXCwQRI2GiIKCAEwABgAjAAOPbEwl7QkAFixQhwV1Q3Wk-y8LBw7TxUBB6BODBsACE1BAAF5KekWcYuWZopAY1kxISzFAgUEAWRGLCQh0lQgWEgNBse4GgstqXFo3Ak0zmwHwwzG43wcEQKAw2Dw+BewHeX3mpG4G0BJw2vAopHBkJc0Nh8MRwGRqPRmIoEZtM2+9sdExdvndAS9Pr9WcDGxxzDDEZ5RLJFKptJBaeIGbtDtGuddfg9gW95RLAZ45ZMkKQYBTVdI8SSmGbraz7adebd-k9BGLn1LQ8ZaG6G1IGw5XMnPL5jCFIvFqfTQltC5zzq7BbXfdem8HQZ3zMw+820tlE4HiqoAniCmrarqc63pm8yLp2+arr2G7+sAZZfnuQFwmwv6HiM7RvGoJ7Tmoc68EAA\" rel=\"noopener noreferrer nofollow\">\u00a0Playground<\/a><\/p>\n<h4>1.3. \u0412\u0441\u0435 \u0432\u043c\u0435\u0441\u0442\u0435<\/h4>\n<pre><code class=\"typescript\">type Get&lt;O, P> = GetWithArray&lt;O, Path&lt;P>>;<\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u0438 \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u0442\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f:\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBACghsAFgHgCoD4oF4qqhAD2AgDsATAZygAMASAbwEsSAzCAJygGkIQBfAHQNmbTgCUIFYH2oAoKFAD8UANo8QAGigCd8JMglT0AXXlQAXLnxFSlGsNYduvGWeVrephZZWnZoSCgAcQhgAHVGJABBdnY4EGQAeS0uTBwua2JyKl83KESzSwzCLLsVESd1LR0BCvFJYC8FJWcQTNsqAGteAHsWfLNmlpDwyMQYuITEjxBjLUNgdEHmyxIIADcOZdWNrf9waBGkrRg04NCI6Nj449gEFFOl2QB6ACooAH0v75-v3AaoABhOAUSSfX4Qj5QV7PWSMAC2YB67GAUHoUAAogBHACucAANloMQRIABjVF8KAsdg9eFQADkAAEAhAALSkxAE-GkADmkmeOOAjHxFHpsn2gVQDUSACMAFYQcnYNFmIXAbmWagAZVJNPx+JlcE4pJxUlpjAoCEYPRIcgUZAQEE1ACYAAwARgAHKz3a7Wa6ACx2qBwQWIZGWejLEhweFOmhRbkEXhQABCHAgAC9mMGFPieqSrTbI8sFKTIiBNQBZHEkRgc3NQPhmZvNiXQQugqg4FRmYlk4DIbF4-HII5SqSyhXkrT0tXc+noLTa3U9fWG42m4Dmy1Cm3UdBLvskxWD4cEsehNDS+Wn2cO4iL5dur0+v2Bg9HhT909D3EX8cb2nYB70kXVGDAPcSCfKA1k2dhDw0Y8Bz-EdL0HCdgCnO8GVDJBkQEGM4xg6hE0IFN03YLMc0Q5Df3PUdAMnW8Z1wsMCPzQsoIEctQBIms6wbWjvxPclUIAq9MOw1j6Tw8N2B4o0yEInF4RlDgYLgjhaOMIA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>. \u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438.<\/p>\n<h3>2. \u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0443\u0442\u0438<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0448\u044c \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 production, \u0442\u0435\u0431\u0435 \u0438\u043d\u043e\u0433\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0438\u043b\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442, \u043d\u043e \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u00a0<code>?<\/code>\u00a0,\u00a0<code>null<\/code>\u00a0\u0438\u043b\u0438<code>undefined<\/code>.<\/p>\n<p>\u0412\u043e\u0437\u044c\u043c\u0435\u043c \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438 \u043f\u043e\u043a\u0440\u043e\u0435\u043c \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435:\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBACghsAFgHgCoD4oF4qqhAD2AgDsATAZygAMASAbwEsSAzCAJygGkIQBfAHQNmbTgCUIFYH2oAoKFAD8UANo8QAGigCd8JMglT0AXXlQAXLnxFSlGsNYduvGWeVrephZZWnZoSCgAcQhgAHVGJABBdnY4EGQAeS0uTBwua2JyKl83KESzSwzCLLsVESd1LR0BCvFJYC8FJWcQTNsqAGteAHsWfLNmlpDwyMQYuITEjxBjLUNgdEHmyxIIADcOZdWNrf9waBGkrRg04NCI6Nj449gEFFOl2QB6ACooAH0v75-v3AaoABhOAUSSfX4Qj5QV7PWSMAC2YB67GAUHoUAAogBHACucAANloMQRIABjVF8KAsdg9eFQADkAAEAhAALSkxAE-GkADmkmeOOAjHxFHpsn2gVQDUSACMAFYQcnYNFmIXAbmWagAZVJNPx+JlcE4pJxUlpjAoCEYPRIcgUZAQEE1ACYAAwARgAHKz3a7Wa6ACx2qBwQWIZGWejLEhweFOmhRbkEXhQABCHAgAC9mMGFPieqSrTbI8sFKTIiBNQBZHEkRgc3NQPhmZvNiXQGA0sg48nWkiyhVKnBR+2SXWMMBCm2KSxSdjMHkAblVkQ1UDnC+X9sds+A85IS7MoaQyJnKqGMbju-3h6G+cLU5IZ5HQyg5dA183y2bClb4pZb4gmCOAqGYbxQMQUiAaCVAwmYxJksAyDYni+LIEcUpSAOirAFo9Jqty9LoFo2q6j0+qGsaprAOalqPtQ6DEfBJI4chuIEuhoRoNK8o4XhDrEERJFul6Pp+oGDFMQoCGsShHEYTxg64QyZBjvOk59kJUBrJs7CMRozGIWxqGcUhmHANh5J4ce4bsAIl4QFp1CJoQKbpuwWY5vphmyexaEKVhvFWQyNnIgI95FiQAjviATk1nWDbedJLHksZ8lceZlnKfSoV2YW7BkPZOLwjKHBaTpHBJVA4FgF2PaPtBYJwclRlyf5XGdj03a9jaWV4QRjnEeue4LlVMmpW1pnIJ13WPn1KmOlpG4HmNKVIZNRwzfVfbzfSqkUOOGk2ktI0HlAAA+UC1qpLDMBAZCra1flTVtPX9kF2W5fZsaDVoy08hdV3kBAt1rA9UmYmtaXtUhr1zR91lhmFEWPtFFYnTegPXSDd3gwZLW+SZm11W9u1fflhUkMVpXsFp2Og-d3nGEAA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>. \u041a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, TypeScript \u0440\u0443\u0433\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u0430. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0440\u0438\u043c\u0435\u0440 \u0438 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e \u043f\u0440\u043e\u0439\u0434\u0435\u043c\u0441\u044f:<\/p>\n<pre><code class=\"typescript\">type ProductionObject = {   description?: string;   title: string;   date: string;   author?: {     name: string;     location?: {       city: string;     };   }; };  type Step1 = Get&lt;ProductionObject, \"author.name\">; type Step2 = Get&lt;   | {       name: string;       location?:         | {             city: string;           }         | undefined;     }   | undefined,   \"name\" >; type Step3 = Get&lt;never, \"\">; type Result = never; \/\/ \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c `string | undefined`<\/code><\/pre>\n<p>\u0422\u0435\u043a\u0443\u0449\u0435\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u044c \u043a\u043b\u044e\u0447 \u0438\u0437 \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c\u00a0<code>undefined<\/code>\u00a0or\u00a0<code>null<\/code>. \u041f\u043e\u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f \u044d\u0442\u043e \u0440\u0435\u0448\u0438\u0442\u044c.<\/p>\n<h4>2.1. \u0423\u0434\u0430\u043b\u044f\u0435\u043c undefined, null \u0438\u043b\u0438 \u043e\u0431\u0430 \u0442\u0438\u043f\u0430 \u0441\u0440\u0430\u0437\u0443<\/h4>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c 3 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0442\u0438\u043f\u0430:<\/p>\n<pre><code class=\"typescript\">type FilterUndefined&lt;T> = T extends undefined ? never : T;  type FilterNull&lt;T> = T extends null ? never : T;  type FilterUndefinedAndNull&lt;T> = FilterUndefined&lt;FilterNull&lt;T>>;<\/code><\/pre>\n<p>\u041c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e\u00a0<code>undefined<\/code>\u00a0\u0438\/\u0438\u043b\u0438\u00a0<code>null<\/code>\u00a0\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e union type, \u0438 \u0435\u0441\u043b\u0438 \u0442\u0430\u043a, \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0438\u0445 \u0438\u0437 \u043d\u0435\u0433\u043e. \u042d\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 &#171;\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439&#187; \u0447\u0430\u0441\u0442\u044c\u044e.<\/p>\n<p>\u0422\u0435\u0441\u0442\u044b, \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u0432\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBAYglgG2BATgVQHYBMIDM4YRYA8AKgHxQC8UpUEAHstgM5QCu2eBRUA-FEIA3VFABctAFCTQkWImQoAcuwQIylGnUbMsbDKoT9BEESnFSZ4aPCSpMOfISwBBbCrUbq8u+i5OiYltFD3UKcmkAegAqKAB9BMSkxNoIFmAoAGEAQxY0+OTCuKhoyMk4AFswAHsUDIBvKABRAEd2bIQAGmaGSABjDIBfKFwUaoqoAHIAAVkIAFo+gAsOhAgMAHM0yPZgRBZJ6TmoPtz8mgBtSSge-uBiVvb1YPt-Hld3Q2IARigAHygACZ-lAAMwgziOd7kbq-AHAgGg8gw663CADB5tDpBBSvKHONxYULESbVQiTEGTYAAd2qFIBVKWKAgEHpgkMMKmZNZlJpdN5TJZk2RnVRTV66Puj2xLz8+KIhOJcKmfLZBjUELezk5yqptOFKJu4rumKeON8Dm4BM+nkhVqInOEqBFYolGOlz1xcvtHyJX3VCEdpmdhrR7qxnotWoVNvUdoCWBBAaDZhdAF0gA\" rel=\"noopener noreferrer nofollow\">Playground<\/a><\/p>\n<h4>2.2. \u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c reducer<\/h4>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u0432\u043e\u0442 \u044d\u0442\u0443 \u0432\u0435\u0442\u043a\u0443\u00a0<code>GetWithArray<\/code>:<\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;O, K> = K extends []   ? O   : K extends [infer Key, ...infer Rest]   ? Key extends keyof O     ? GetWithArray&lt;O[Key], Rest>     : never \/\/ &lt;= \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0437\u0434\u0435\u0441\u044c ?   : never;<\/code><\/pre>\n<ol>\n<li>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u043a\u043b\u044e\u0447 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u0441\u00a0<code>undefined<\/code>\u00a0\u0438\/\u0438\u043b\u0438\u00a0<code>null<\/code><\/p>\n<\/li>\n<li>\n<p>\u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0433\u043e \u043d\u0435\u0442 (\u0442\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u00a0<code>undefined<\/code>)<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"typescript\">type GetWithArray&lt;O, K> = K extends []   ? O   : K extends [infer Key, ...infer Rest]   ? Key extends keyof O     ? GetWithArray&lt;O[Key], Rest>     : Key extends keyof FilterUndefinedAndNull&lt;O>     ? GetWithArray&lt;FilterUndefinedAndNull&lt;O>[Key], Rest> | undefined     : undefined   : never;<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0437\u0434\u0435\u0441\u044c \u0442\u0435\u0441\u0442\u044b \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u0442\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e (\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBAYglgG2BATgVQHYBMIDM4YRYA8AKgHxQC8UpUEAHstgM5QCu2eBRUA-FEIA3VFABctAFCTQkWImQoAcuwQIylGnUbMsbDKoT9BEESnFSZ4aPCSpMOfISwBBbCrUbq8u+i5OiYltFD3UKcmlZaABxCGAAdThgAAsXFBQAQxBiAHkAGigAaU0i+iYIVigAbQBdSShjHPqLQrLdNiqCXFFCiBACgDohrtEAJQgWYDqGhoFekDaKvSgAaz6Ae1woJpmZgViEpNT0rNyq+ZqC8cmI3YaJecXKtZBNn0UHbmc3LFDc27usygB0SKTSmWywXs-h4rnchn+5z6lyg12AlAAPhwYc5moCJJxHLC8RZhKhpAB6ABUUAA+vSGYyGbQJsAoABhDIsCZ0pl82lQKkUyRwAC2YHWKDZAG8oABRACO7AyCAKcoYkAAxmyAL5QXAodaiqAAcgAAlEALSa5IqhAVADmEwp7GAiBYJsi1igAAVDVh2Nq4OsMDkAEYAKwg2u80uaOBYmpQcDAbpDfAkk2TGAdzTdwHtmeA2dzDSwGWQRZLzQyruSkozUDjuwwGVFECrBFLMwQ601FeDGEbzbumqSIE7OZJOuaM5nVjk-e5bBoVWa6q1wGIiuV6hBR3Bpz96wDQZD4aj2oKVRN+ftJpq5AKWa75Cf6410a3O5VxH3YJObJj1PNNQ0jL9rxNctkAfJ8oBfHM3zyD9N23JVf3-Y4IWIYDA1Ai8IOqKCJiTFNQNg59iy7KAsUJL4iCQlCvzQ3c-ziUEsKPf08MHAiryI2sUklE0ChNVt2wo+CqJzGjsSJZxGIaDdmJ-Pd2IPQCcO4s8wMvYBIME+sUBE01e37cjRLHUBJIQh1ZLogIsEU+VP21FiMPUgDsNwnS+P0gS62EyyMhQLATLE9hRTDVBJIc2FGJqIA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>).<\/p>\n<h2>3. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u0443\u0442\u0438 \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0438<\/h2>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0431\u0435\u0440\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c \u0438 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c:<\/p>\n<pre><code class=\"typescript\">type ProductionObject = {   posts: {     title: string;     description?: string;     poster?: string;     html: string;   }[]; };  type Step1 = Get&lt;ProductionObject, \"posts.0\">; type Step2 = Get&lt;   {     title: string;     description?: string;     poster?: string;     html: string;   }[],   \"0\" >; type Step3 = Get&lt;undefined, \"\">; type Result = undefined; \/\/ ? \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c `string | undefined`<\/code><\/pre>\n<p>\u0412 JavaScript \u043c\u044b \u0431\u044b \u0445\u043e\u0434\u0438\u043b\u0438 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u043c:<\/p>\n<pre><code class=\"javascript\">const get = (arr, path) => {   const keys = path.split(\".\");    return keys.reduce((currentArr, key) => currentArr[key], arr); };<\/code><\/pre>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043a\u043b\u044e\u0447 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c\u00a0<code>string<\/code>\u00a0\u0438\u043b\u0438\u00a0<code>number<\/code>,\u00a0<code>Path<\/code>\u00a0\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u044b\u043c:<\/p>\n<pre><code class=\"typescript\">type Path&lt;T> = T extends `${infer Key}.${infer Rest}`   ? [Key, ...Path&lt;Rest>]   : T extends `${infer Key}`   ? [Key]   : [];<\/code><\/pre>\n<h4>3.1. Reducer \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430<\/h4>\n<p>\u041a\u0430\u043a \u0438 \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u00a0<code>keys.reduce<\/code>\u00a0. \u0414\u043b\u044f TypeScript \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u00a0<code>GetWithArray<\/code>\u00a0. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432, \u0430 \u0437\u0430\u0442\u0435\u043c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438\u00a0<code>GetWithArray<\/code>\u00a0\u0432 \u043e\u0434\u043d\u043e.<\/p>\n<p>\u0421\u043f\u0435\u0440\u0432\u0430 \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0430. \u0412\u043e\u0437\u044c\u043c\u0435\u043c\u00a0<code>A<\/code>\u00a0\u0432\u043c\u0435\u0441\u0442\u043e\u00a0<code>O<\/code>\u00a0\u043f\u043e \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c:<\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;A, K> = K extends []   ? A   : K extends [infer Key, ...infer Rest]   ? Key extends keyof A     ? GetWithArray&lt;A[Key], Rest>     : never   : never;<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBA4hwHUCWwAWBBATpghiAPOgDRQDSAfFALxlQQAewEAdgCYDOUA2gLoBQUKAH4o6AVABctBkzacuSZgDMImMhBAkAdDsUq1AJQjtg-QYJGkNdRiw5QA1hoD2S0ePPDY8ZGiy4CdC4rEB4SIxNyD3MpZggAN1Vo2ISkvgB6ACooAH08-IL8qAAVY2AoAGEcdmNcwvqcqEz0viQAWzBnTHKAbygAUQBHAFccABsSfvpIAGNygF8oJUxnNqgAcgABUEgAWhnUcbGWAHNjdOHgJDH2db4+HehSkwB5ACMAKwg56m5xdPSUAADOIAAYAZRmKzGYzeODUM2GJlWSHYOCuzmYoKI-0BAEYwQAmIF4gAcuzxQN2QIALNjcVBCeIuNEAYytCDPCZMIoTjjPGzCVoCZ4ABTc3lQAA+UGYwzab1UAEpePzzIKtEzPJgIDhWJixiBZfLFZheOJ+DwANz3R5QGbVWo0FmCKazYD4IajMb4OCIFAYbB4fDPYDvL5zEhcdZA9Y8cgkCFQ5wwuEIpHAFFojFY8gJ8Ru74er3jX0+AP+YOh8NFqPrPFxhNQUHEskUqm00F5tWFuaekalv2+QMBENlGuR7jrQnrEgxxskCXME7dgvTIv971l-1+IMEaufWtTmdzhtz2PxxfAHnL6XGhWqO-DNgQJSKCCsVeu9d9ks+ocVnuY6vIek7RieGwQdOC73qaT4vm+cSfvm37upug7lruo4HhGwB1gAzDBz6sK+77ITiPBAA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>, \u043c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438:<\/p>\n<p>1. \u041c\u0430\u0441\u0441\u0438\u0432\u044b \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u043a\u043b\u044e\u0447\u0435\u0439 \u0441 \u0442\u0438\u043f\u043e\u043c \u00a0<code>string<\/code>\u00a0:<\/p>\n<pre><code class=\"typescript\">type Step1 = GetWithArray&lt;string[], \"1\">; type Step2 = \"1\" extends keyof string[] ? string[][\"1\"] : never; type Result = never; \/\/ ? \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c `string | undefined`<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c\u00a0<code>'1' extends keyof string[]<\/code>\u00a0\u0432\u0441\u0435\u0433\u0434\u0430 \u043b\u043e\u0436\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u00a0<code>never<\/code>.<\/p>\n<p>2. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u043c\u00a0<code>readonly<\/code><\/p>\n<pre><code class=\"typescript\">type Step1 = GetWithArray&lt;readonly string[], \"1\">; type Step2 = \"1\" extends keyof (readonly string[])   ? (readonly string[])[\"1\"]   : never; type Result = never; \/\/ ? \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c `string | undefined`<\/code><\/pre>\n<p>3. \u041a\u043e\u0440\u0442\u0435\u0436\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440\u00a0<code>[0, 1, 2]<\/code>) \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u00a0<code>never<\/code>\u00a0\u0432\u043c\u0435\u0441\u0442\u043e\u00a0<code>undefined<\/code>:<\/p>\n<pre><code class=\"typescript\">type Step1 = GetWithArray&lt;[0, 1, 2], \"3\">; type Step2 = \"3\" extends keyof [0, 1, 2] ? [0, 1, 2][\"3\"] : never; type Result = never; \/\/ ? \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c `undefined`<\/code><\/pre>\n<p>\u041f\u043e\u0439\u0434\u0435\u043c \u0447\u0438\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e.<\/p>\n<h4>3.2. \u0412\u044b\u0432\u043e\u0434\u0438\u043c T | undefined<\/h4>\n<pre><code class=\"typescript\">type GetWithArray&lt;A, K> = K extends []   ? A   : K extends [infer Key, ...infer Rest]   ? Key extends keyof A     ? GetWithArray&lt;A[Key], Rest>     : never \/\/ &lt;= \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0437\u0434\u0435\u0441\u044c ?   : never;<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u00a0<code>T | undefined<\/code>\u00a0\u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 (\u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0440\u0438 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0438 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443 \u043c\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u043c, \u0435\u0441\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438\u043b\u0438 \u043d\u0435\u0442), \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u00a0<code>T<\/code>:<\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;A, K> = K extends []   ? A   : K extends [infer Key, ...infer Rest]   ? Key extends keyof A     ? GetWithArray&lt;A[Key], Rest>     : A extends readonly (infer T)[]     ? GetWithArray&lt;T | undefined, Rest>     : never   : never;<\/code><\/pre>\n<p>\u042f \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u00a0<code>A extends readonly (infer T)[]<\/code>\u00a0, \u0442.\u043a. \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 (\u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u00a0<code>readonly<\/code>) \u044d\u0442\u043e \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043d\u043e.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0447\u0438\u043d\u0438\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436\u0438. \u041f\u0440\u0438\u043c\u0435\u0440 \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBA4hwHUCWwAWBBATpghiAPOgDRQDSAfFALxlQQAewEAdgCYDOUA2gLoBQUKAH4o6AVABctBkzacuSZgDMImMhBAkAdDsUq1AJQjtg-QYJGkNdRiw5QA1hoD2S0ePPDY8ZGiy4CdC4rEB4SIxNyD3MpdBtZe0wIHFZnZgAbECgACj1VKAAVAEpeaM8ROEQUDGw8fAKoAB8oAFc2CCVFCFZw42Aoz08pZggAN1Vo4bGJvgB6ACooAH0V1bXVwr6oAGEcdmNl9aOlqHnZviQAWzBnTGAoAG8oAFEARxacdJJn+kgAY3uAF8oEpMM5LlAAOQAAVAkAAtH9UJ90iwAObGWYtYBIdLsSF8Phw6AFPoAeQARgArCAA6jccSzWZQAAM4gABgBlP5g9LpCk4NR-FomcFIdg4HFpdlERnMgCMHIATCz5QAOeHylnwlkAFhlcqgSvEXGiTKNWjZnhMmEUaNlnnNSq0is82RtdqaUGYLUuFNUJTCZuZzuNniSKTSmW9vv9mFKgn4PAA3ITiVA-nsDjRTYIfv9gPg3h90vhKr4agF6uTqbTgCQuJCWZCeOQSFyec4+QKhSLgGKJVLmOzyG3xPm60X3p8yz5qv46qSTJSaQCG5D5S221B2Sr1ZrtXqR2O879J8WZ+X57UCEvgCu6+ulZCSE2tyQPcw0aOHS8zwCpxLWcqj8G9q2XWs124SFn1fTdX2bVsP2AW0vy9H0-XyZo2lYDoulYH9x3-QsL1LK9QKrO8HygxtYKhOiYPfGNMLUbD2k6EYCJPP8C0Ay85woxca1XetoIAZiYnC8M4wieCAA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>.<\/p>\n<h4>3.3. \u041a\u043e\u0440\u0442\u0435\u0436\u0438<\/h4>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0431\u043e\u0431\u0449\u0430\u044e\u0449\u0438\u0439 \u0442\u0438\u043f, \u043a\u0430\u043a \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 (\u043d\u0443 \u0438 \u0435\u0449\u0435\u00a0<code>undefined<\/code>\u00a0\u0432 \u043f\u0440\u0438\u0434\u0430\u0447\u0443)<\/p>\n<pre><code class=\"typescript\">type Step1 = GetWithArray&lt;[0, 1, 2], \"3\">; type Step2 = \"3\" extends keyof [0, 1, 2] \/\/ &lt;= false   ? [0, 1, 2][\"3\"]   : [0, 1, 2] extends (infer T)[] \/\/ &lt;= true   ? T | undefined   : [0, 1, 2] extends readonly (infer T)[]   ? T | undefined   : never;  type Result = 0 | 1 | 2 | undefined; \/\/ ? \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c `undefined`<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u0441 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439, \u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0443 \u0441\u00a0<code>extends<\/code>\u00a0\u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 (\u043d\u0430\u0437\u043e\u0432\u0435\u043c \u044d\u0442\u0443 \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0443\u00a0<code>ExtendsTable<\/code>) \u0438 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u0442\u0438\u043f, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0438:<\/p>\n<pre><code class=\"typescript\">type ExtendsTableRow&lt;T extends any[], E extends any> = {   [K in keyof T]: E extends T[K] ? true : false; };  type ExtendsTable&lt;T extends any[]> = {   [K in keyof T]: ExtendsTableRow&lt;T, T[K]>; };<\/code><\/pre>\n<p>\u0412\u043e\u0437\u044c\u043c\u0435\u043c 4 \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u0430:<\/p>\n<ol>\n<li>\n<p><code>[0]<\/code><\/p>\n<\/li>\n<li>\n<p><code>number[]<\/code><\/p>\n<\/li>\n<li>\n<p><code>readonly number[]<\/code><\/p>\n<\/li>\n<li>\n<p><code>any[]<\/code><\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"typescript\">type Result = ExtendsTable&lt;[[0], number[], readonly number[], any[]]&gt;;<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u0440\u0438\u0441\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"316\" width=\"316\">\n<p align=\"left\">\n<\/td>\n<td data-colwidth=\"76\" width=\"76\">\n<p align=\"left\"><code>[0]<\/code><\/p>\n<\/td>\n<td data-colwidth=\"116\" width=\"116\">\n<p align=\"left\"><code>number[]<\/code><\/p>\n<\/td>\n<td data-colwidth=\"144\" width=\"144\">\n<p align=\"left\"><code>readonly number[]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>any[]<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"316\" width=\"316\">\n<p align=\"left\"><code>[0]<\/code><\/p>\n<\/td>\n<td data-colwidth=\"76\" width=\"76\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td data-colwidth=\"116\" width=\"116\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td data-colwidth=\"144\" width=\"144\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"316\" width=\"316\">\n<p align=\"left\"><code>number[]<\/code><\/p>\n<\/td>\n<td data-colwidth=\"76\" width=\"76\">\n<p align=\"left\">\u200b-<\/p>\n<\/td>\n<td data-colwidth=\"116\" width=\"116\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td data-colwidth=\"144\" width=\"144\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"316\" width=\"316\">\n<p align=\"left\"><code>readonly number[]<\/code><\/p>\n<\/td>\n<td data-colwidth=\"76\" width=\"76\">\n<p align=\"left\">\u200b-<\/p>\n<\/td>\n<td data-colwidth=\"116\" width=\"116\">\n<p align=\"left\">\u200b-<\/p>\n<\/td>\n<td data-colwidth=\"144\" width=\"144\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u200b-<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"316\" width=\"316\">\n<p align=\"left\"><code>any[]<\/code><\/p>\n<\/td>\n<td data-colwidth=\"76\" width=\"76\">\n<p align=\"left\">\u200b-<\/p>\n<\/td>\n<td data-colwidth=\"116\" width=\"116\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td data-colwidth=\"144\" width=\"144\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/th>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0430 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0438 \u0437\u043d\u0430\u043a \u043f\u043b\u044e\u0441\u0430 \u200b&#187;+&#187;, \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u0441\u0442\u0440\u043e\u0447\u043a\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u0430 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u043c. \u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432:<\/p>\n<ul>\n<li>\n<p><code>[0] extends [0]<\/code><\/p>\n<\/li>\n<li>\n<p><code>number[] extends readonly number[]<\/code><\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0435\u0441\u043b\u0438 \u043d\u0430 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0438 \u200b\u0437\u043d\u0430\u043a \u043c\u0438\u043d\u0443\u0441\u0430&#187;-&#171;, \u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430 \u043d\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043b\u043e\u043d\u043a\u043e\u0439. \u041f\u0430\u0440\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432:<\/p>\n<ul>\n<li>\n<p><code>number[] extends [0]<\/code><\/p>\n<\/li>\n<li>\n<p><code>readonly number[] extends number[]<\/code><\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u043e\u0437\u044c\u043c\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0441\u00a0<code>any[]<\/code>: \u0434\u043b\u044f \u043a\u043e\u043b\u043e\u043d\u043a\u0438\u00a0<code>[0]<\/code>\u00a0\u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0437\u043d\u0430\u043a \u043c\u0438\u043d\u0443\u0441\u0430 &#171;-&#171;\u200b, \u043a\u043e\u0433\u0434\u0430 \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 (\u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432) \u2013 \u044d\u0442\u043e \u200b\u0437\u043d\u0430\u043a \u043f\u043b\u044e\u0441\u0430 &#171;+&#187;.<\/p>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043c\u044b \u043d\u0430\u0448\u043b\u0438 \u043e\u0442\u0432\u0435\u0442!<\/p>\n<p>\u041c\u044b \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u044d\u0442\u043e\u0442 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u0442\u0438\u043f\u00a0<code>any[] extends A<\/code>\u00a0\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u043a\u00a0<code>GetWithArray<\/code>:<\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;A, K> = K extends []   ? A   : K extends [infer Key, ...infer Rest]   ? any[] extends A     ? \/\/ \u043c\u0430\u0441\u0441\u0438\u0432\u044b       A extends readonly (infer T)[]       ? GetWithArray&lt;T | undefined, Rest>       : undefined     : \/\/ \u043a\u043e\u0440\u0442\u0435\u0436\u0438     Key extends keyof A     ? GetWithArray&lt;A[Key], Rest>     : undefined   : never;<\/code><\/pre>\n<ol>\n<li>\n<p>\u041c\u044b \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0442 \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430\u00a0<code>any[] extends A<\/code><\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u00a0<code>T | undefined<\/code><\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439, \u043c\u044b \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0438\u043d\u0434\u0435\u043a\u0441 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442<\/p>\n<\/li>\n<li>\n<p>\u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u00a0<code>undefined<\/code><\/p>\n<\/li>\n<\/ol>\n<p>\u0415\u0441\u043b\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0435\u0449\u0435 \u0440\u0430\u0437 \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c \u043d\u0430 \u0432\u0441\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u0435 \u043d\u0430\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBA4hwHUCWwAWBBATpghiAPOgDRQDSAfFALxlQQAewEAdgCYDOUA2gLoBQUKAH4o6AVABctBkzacuSZgDMImMhBAkAdDsUq1AJQjtg-QYJE5mIXnUYsOo8eagB6V1BzY87Z+ZHodrKOmBA4rAD2zAA2IFAAFHqqUAAqAJS8fi4icIgoGN4EKVAAPlAArmwQSooQrCRGJuRZ5lKVrNW1rC3uUMDlYNHGLVKkGkEOnADWGhFKTi7ZsPDIaFi4BOhcYyA8DcbAzYutFVU1zHV+UhcAbqp8fK4AVFAA+u8fnx+pB1AAwjh2MY3l9Qa8oE9XHwkABbMARTDAKAAbygAFEAI7lHDREho+iQADGSIAvlAlJgIjCoAByAACoEgAFpCagcUNmABzYyucrAJDRdg0h6M6ApA4AeQARgArCDE6jccS9AAM4gABgBlQmU6LRKVeKCE8omKlIdg4flRdVEZUeACMGoATCr7QAOJn2lVMlUAFhtdqgTvEXD8vSdWjVLhMmEUnNtLnDWkdLniMbjpSgzHKMKlqgyezDHgjwZcoXCUViWZzecwmUE-B4AG4ReBoITAcCaKHBPiicB8JjsdF8LlVgUNvhxSZpXLiSQuDSVTSeOQSFqdRE9Qa1MbTTDzZakNbyGvxH35QOhzjRyt8us8FPJbLLwuafaV2uoOqXe7Pd6-XVU8E3RAlL0HLEbzHe9CifGcX3nbgaSdGkSCXT8SHTLlgPPMDiQg4dbzyNZYOnYBZ1fJCULQj80OXVdMOAWMuUzbNc2SMp2k6C5WBw3s8KvSCR2gkjJzIijEMXajaWk5CMOrdi1E4s4uj40D+wIqC71Ex9xIQ4A3wAZnkrjzjqHCeCAA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>.<\/p>\n<h2>4. \u041e\u0431\u0449\u0435\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432:<\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;O, K> = K extends []   ? O   : K extends [infer Key, ...infer Rest]   ? Key extends keyof O     ? GetWithArray&lt;O[Key], Rest>     : Key extends keyof FilterUndefinedAndNull&lt;O>     ? GetWithArray&lt;FilterUndefinedAndNull&lt;O>[Key], Rest> | undefined     : undefined   : never;<\/code><\/pre>\n<p>\u0438 \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432:<\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;A, K> = K extends []   ? A   : K extends [infer Key, ...infer Rest]   ? any[] extends A     ? \/\/ arrays       A extends readonly (infer T)[]       ? GetWithArray&lt;T | undefined, Rest>       : undefined     : \/\/ tuples     Key extends keyof A     ? GetWithArray&lt;A[Key], Rest>     : undefined   : never;<\/code><\/pre>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0434\u0432\u0430 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0442\u0438\u043f\u0430: \u00a0<code>ExtractFromObject<\/code>\u00a0\u0438\u00a0<code>ExtractFromArray<\/code>, \u0433\u0434\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0437\u043d\u0430\u044f, \u0441 \u043a\u0430\u043a\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c:<\/p>\n<pre><code class=\"typescript\">type ExtractFromObject&lt;   O extends Record&lt;PropertyKey, unknown>,   K > = K extends keyof O   ? O[K]   : K extends keyof FilterUndefinedAndNull&lt;O>   ? FilterUndefinedAndNull&lt;O>[K] | undefined   : undefined;  type ExtractFromArray&lt;A extends readonly any[], K> = any[] extends A   ? A extends readonly (infer T)[]     ? T | undefined     : undefined   : K extends keyof A   ? A[K]   : undefined;<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c &#171;\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f&#187; (<a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/generics.html#generic-constraints\" rel=\"noopener noreferrer nofollow\">Generic Constrains<\/a>):<\/p>\n<ol>\n<li>\n<p>\u0414\u043b\u044f\u00a0<code>ExtractFromObject<\/code>\u00a0\u2013 \u044d\u0442\u043e\u00a0<code>O extends Record&lt;PropertyKey, unknown><\/code>. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e\u00a0<code>O<\/code>\u00a0\u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u043b\u044e\u0431\u043e\u0433\u043e \u0432\u0438\u0434\u0430<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f\u00a0<code>ExtractFromArray<\/code>\u00a0\u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e: \u00a0<code>A extends readonly any[]<\/code>\u00a0\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0438<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0432\u00a0<code>GetWithArray<\/code>\u00a0\u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;O, K> = K extends []   ? O   : K extends [infer Key, ...infer Rest]   ? O extends Record&lt;PropertyKey, unknown>     ? GetWithArray&lt;ExtractFromObject&lt;O, Key>, Rest>     : O extends readonly any[]     ? GetWithArray&lt;ExtractFromArray&lt;O, Key>, Rest>     : undefined   : never;<\/code><\/pre>\n<p>\u042d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u044f \u0442\u043e\u0436\u0435 \u043f\u043e\u043a\u0440\u044b\u043b \u0442\u0435\u0441\u0442\u0430\u043c\u0438. \u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBAYglgG2BATgVQHYBMIDM4YRYA8AKgHxQC8UpUEAHstgM5QCu2eBRUA-FEIA3VFABctAFChIsRMhQA5dggRlKNOo2ZY2GFQn6CIIlOKkzo8JKkw58hLAEFsy1eupyb6Lg6LFrBTc1CnJJaXBoAFEmFABDAGNgGBQAewBbAHkAIwArCCTiTPomCFYoACUC1JQSAAU0yBRQAGkIEAAaDgwAawxUgHcMci6WjSgWkp02HvbU3ChMySgjTIBtFoBdZfNJ7TLdKFmQea8FO25HFyxgorCVlYFA218eZ1cDO43NqAAfbvsbx2KwknEBjnCligMWA8SSKQyThQ8RAxCcUwObBQEDiWFSGAQICgcQwIDWm1G4xJZJ++3KTh2AnRdMO2Nx+MJUAAFARcKJSABKcnAox0f5gy5EEWg14QkETDHlY6nBkPIxOb7SgGSrCQyJQADiEGAAHU4MAABZIlFFSmePalcrCx6LHYSB3TKBrXmiNqdKAAOiDPrMVRYwG2aoExRZbCqCRq9UaqFa7S6nD6g2GIpdRtN5qtyLiqJhcOSaSyeQKwFtE3aI0qEHD9zV5hjjtZOLxBKJ1OdrdzxrNlutxeIpcS5cRRdRmVG9a6YeALYHMvBUrVEmEqHCAHoAFRQAD6J9PZ9PtCbwCgAGE4iwm8fz8+j1B97vJHB0mAateAN7QgAjuwcQIF0MSQEkUAAL5QLgFZQAA5AAApYAC0CQWqBCBlAA5k2u7sMAiAsIheqyA0qRYOwSRwPiOT5FBNB-jsxHADhEjhigBC4TsOAsAk3FgMR+J8JxsI8XxcTIFu7DpNkO4rHEREWjUYlQCxaoYHE6QQOJ3EYLxaoIKkCTSXRGDqZprYJOaID6ZJarQTszkrMAcS4Sw6lrIhbJJIhXSIZYAlCcAAVIUIcA4KkiGRlALBwLh2nAOw2LqYhTg4Qw7RQAAQqgEAAF4EGRKw-uGLASGy3acgBFrAOkCAOYZMH9qYCX4pV3JcTxfyCHJCkoEK2zOREshmQ+bA0GsOwQdW47AaBxB5sOhY2pR1G0fRVZJF0PlsThsUNj1hnkCMs0MJBNZRItagrQWo6ohtNEiRgDHVntiH8YJcDCRZR1dCduF9RKfhYGdHQXVdC0gXdQ4PTOxDPVtb07cAn1YNJEAA-18moBDUPzTdsPLfDI6I8jr3vbtXqIcplo1OFiHabpONAyDspEATKxzYUxNLfd5PrWkm1U2jn306pKBMyZZmvUztmgGzEkteKnPg+dPOXUTt2k-mQtjpTFnU+jtOS4zgWy+Z+JM7iWDYiwpGbA2oNvNz0La3zuuC2thsiy9xvi2bKkW0hglEGUxGgaRgUAAw467jju7z13e2TvtPf7KMm597meUz8fO4FflhRz64a5DWvQ-zcP6xnSNZ2LjGm-tHkx0hADMCfq8nnupyTPuPQ3VEB9tzefQlSXSal2NF0hmWMDl+XYsVGCIWXOq99Xad10PRtjx9tPlcA7eIYXDZ1Q1TXxSrwOwWr5dbzrA-p3vjeB+PR+pBVBdM-VjXKwMsDB+m9NYe23i-XeFN34Hxpj5dqFlT7n0BrfPq+g8ZmBAWDAmmwgA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>.<\/p>\n<h3>5. \u0421\u0432\u044f\u0437\u043a\u0430 \u0441 JavaScript<\/h3>\n<p>\u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u0440\u0435\u0448\u0435\u043d\u0438\u044e \u0432 JavaScript:<\/p>\n<pre><code class=\"javascript\">const get = (obj, path) => {   const keys = path.split(\".\");    return keys.reduce((currentObj, key) => currentObj[key], obj); };<\/code><\/pre>\n<p>\u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u00a0<code>lodash<\/code>\u00a0\u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u0433\u0434\u0435 \u0435\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u00a0<code>get<\/code>. \u0415\u0441\u043b\u0438 \u0432\u044b \u0432\u044b\u0433\u043b\u044f\u043d\u0435\u0442\u0435 \u043d\u0430\u00a0<a href=\"https:\/\/github.com\/DefinitelyTyped\/DefinitelyTyped\/blob\/master\/types\/lodash\/common\/object.d.ts#L1022\" rel=\"noopener noreferrer nofollow\">common\/object.d.ts<\/a>\u00a0\u0432<code>@types\/lodash<\/code>, \u0442\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0433\u043e\u0440\u0447\u0438\u0442\u0435\u0441\u044c. \u0412\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0432\u044b\u0437\u043e\u0432\u00a0<code>get<\/code>\u00a0\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u00a0<code>any<\/code>\u00a0:\u00a0<a href=\"https:\/\/codesandbox.io\/s\/typescript-lodash-types-ndhvf?file=\/src\/index.type.ts:1379-1856\" rel=\"noopener noreferrer nofollow\">typescript-lodash-types<\/a><\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0437\u0430\u043c\u0435\u043d\u0438\u043c\u00a0<code>reduce<\/code>\u00a0\u043d\u0430 \u0446\u0438\u043a\u043b \u0441\u00a0<code>for<\/code>\u00a0(\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440\u00a0<code>for-of<\/code>), \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0430\u043d\u043d\u0438\u0439 \u0432\u044b\u0445\u043e\u0434 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c, \u0435\u0441\u043b\u0438 \u043e\u043d\u043e\u00a0<code>undefined<\/code>\u00a0\u0438\u043b\u0438\u00a0<code>null<\/code>:<\/p>\n<pre><code class=\"javascript\">export function get = (obj, path) => {   const keys = path.split(\".\");    let currentObj = obj;   for (const key of keys) {     const value = currentObj[key];     if (value === undefined || value === null) {       return undefined;     }      currentObj = value;   }    return currentObj; }<\/code><\/pre>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043a\u0440\u043e\u0435\u043c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e\u00a0<code>get<\/code>\u00a0\u0442\u0438\u043f\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0448\u0430\u0433\u0430\u0445. \u0420\u0430\u0437\u0434\u0435\u043b\u0438\u043c \u044d\u0442\u043e \u043d\u0430 \u0434\u0432\u0430 \u0441\u043b\u0443\u0447\u0430\u044f:<\/p>\n<ol>\n<li>\n<p>\u0422\u0438\u043f\u00a0<code>Get<\/code>\u00a0\u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0433\u0434\u0430 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u044b \u0438 \u0442\u0438\u043f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u0442\u043e\u0440\u0443\u044e \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 \u0447\u0438\u0441\u043b\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0443\u0442\u0438)<\/p>\n<\/li>\n<\/ol>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u00a0<a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/functions.html#function-overloads\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0443<\/a>, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u00a0<code>function<\/code>, \u0430 \u043d\u0435 \u0441\u0442\u0440\u0435\u043b\u043e\u0447\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"typescript\">export function get(obj: Record&lt;string, unknown>, path: string): unknown {   const keys = path.split(\".\");    let currentObj = obj;   for (const key of keys) {     const value = currentObj[key];     if (value === undefined || value === null) {       return undefined;     }      currentObj = value as Record&lt;string, unknown>;   }    return currentObj; }<\/code><\/pre>\n<p>\u041f\u043e\u0447\u0442\u0438 \u0433\u043e\u0442\u043e\u0432\u043e. \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0438\u043f\u00a0<code>Get<\/code>\u00a0:<\/p>\n<pre><code class=\"typescript\">\/\/ strict types ? export function get&lt;O, K extends string>(obj: O, path: K): Get&lt;O, K>; \/\/ fallback ? export function get(obj: Record&lt;string, unknown>, path: string): unknown {   const keys = path.split(\".\");    let currentObj = obj;   for (const key of keys) {     const value = currentObj[key];     if (value === undefined || value === null) {       return undefined;     }      currentObj = value as Record&lt;string, unknown>;   }    return currentObj; }<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u044f \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043b \u043d\u0430\u00a0<a href=\"https:\/\/codesandbox.io\/s\/typescript-get-implementation-types-gnsvo?file=\/src\/get\/index.type.ts:1584-1598\" rel=\"noopener noreferrer nofollow\">Codesandbox<\/a>:<\/p>\n<ol>\n<li>\n<p><a href=\"https:\/\/codesandbox.io\/s\/typescript-get-implementation-types-gnsvo?file=\/src\/get\/index.ts:1027-1096\" rel=\"noopener noreferrer nofollow\">\u041c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e\u00a0<\/a><code>get<\/code><a href=\"https:\/\/codesandbox.io\/s\/typescript-get-implementation-types-gnsvo?file=\/src\/get\/index.ts:1027-1096\" rel=\"noopener noreferrer nofollow\">\u00a0\u0441 \u0442\u0438\u043f\u0430\u043c\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/codesandbox.io\/s\/typescript-get-implementation-types-gnsvo?file=\/src\/get\/index.type.ts:1584-1598\" rel=\"noopener noreferrer nofollow\">\u041c\u044b \u043f\u043e\u043a\u0440\u044b\u043b\u0438 \u0442\u0438\u043f\u044b \u0442\u0435\u0441\u0442\u0430\u043c\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/codesandbox.io\/s\/typescript-get-implementation-types-gnsvo?file=\/src\/get\/index.test.ts:490-516\" rel=\"noopener noreferrer nofollow\">\u041c\u044b \u043f\u043e\u043a\u0440\u044b\u043b\u0438 \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e\u00a0<\/a><code>get<\/code><\/p>\n<\/li>\n<\/ol>\n<h3>\u0422\u0435\u0440\u043c\u0438\u043d\u043e\u0433\u0438\u044f<\/h3>\n<p>\u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u0435\u0440\u043c\u0438\u043d\u044b \u0438\u0437 TypeScript:<\/p>\n<p>1.<a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/release-notes\/typescript-1-3.html#tuple-types\" rel=\"noopener noreferrer nofollow\"> \u041a\u043e\u0440\u0442\u0435\u0436\u0438<\/a>\u00a0\u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 TypeScript 1.3, \u043d\u043e \u0432\u0430\u0440\u0438\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u00a0(<a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/release-notes\/typescript-4-0.html#variadic-tuple-types\" rel=\"noopener noreferrer nofollow\">Variadic Tuple Types<\/a>) \u0431\u044b\u043b \u0432\u044b\u043f\u0443\u0449\u0435\u043d \u0432 \u0432\u0435\u0440\u0441\u0438\u0438 4.0, \u0442\u0430\u043a \u0447\u0442\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c spread \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439<\/p>\n<pre><code class=\"typescript\">\/\/ \u041a\u043e\u0440\u0442\u0435\u0436\u0438 type Digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];  type Name =   | [first: string, last: string]   | [first: string, middle: string, last: string];  \/\/ \u041a\u043e\u0440\u0442\u0435\u0436\u0438, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \"variadic\" type AnyArray = readonly any[];  type Merge&lt;T extends AnyArray, U extends AnyArray> = [...T, ...U];  type Result = Merge&lt;[1, 2], [3, 4]>; \/\/   ^? [1, 2, 3, 4] ?<\/code><\/pre>\n<p>2. \u0423\u0441\u043b\u043e\u0432\u043d\u044b\u0435 \u0442\u0438\u043f\u044b (<a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/release-notes\/typescript-2-8.html#conditional-types\" rel=\"noopener noreferrer nofollow\">Conditional types<\/a>)\u00a0\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 TypeScript 2.8<\/p>\n<pre><code class=\"typescript\">type FilterUndefined&lt;T> = T extends undefined ? never : T;<\/code><\/pre>\n<p>3.<a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/release-notes\/typescript-2-8.html#type-inference-in-conditional-types\" rel=\"noopener noreferrer nofollow\"> \u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e\u00a0infer<\/a>\u00a0 \u0432 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0445 \u0442\u0438\u043f\u0430\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 TypeScript 2.8<\/p>\n<pre><code class=\"typescript\">type AnyFunction = (...args: any) => any;  type MyParameters&lt;TFunction extends AnyFunction> = TFunction extends (   ...args: infer TParameters ) => any   ? TParameters   : never;<\/code><\/pre>\n<p>4. \u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0435 \u0442\u0438\u043f\u044b (<a href=\"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-4-1\/#recursive-conditional-types\" rel=\"noopener noreferrer nofollow\">Recursive conditional types<\/a>) \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 TypeScript 4.1<\/p>\n<pre><code class=\"typescript\">type ElementType&lt;T> = T extends ReadonlyArray&lt;infer U> ? ElementType&lt;U> : T;<\/code><\/pre>\n<p>5. \u0428\u0430\u0431\u043b\u043e\u043d\u044b \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u0447\u043d\u044b\u0445 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u043e\u0432 (<a href=\"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-4-1\/#template-literal-types\" rel=\"noopener noreferrer nofollow\">Template Literal types<\/a>) \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 TypeScript 4.1<\/p>\n<pre><code class=\"typescript\">type Fruit = \"lemon\" | \"orange\" | \"apple\"; type Quantity = 1 | 2 | 3;  type ShoppingList = `${Quantity} ${Fruit}`; \/\/   ^? '1 lemon' | '1 orange' | '1 apple' | ... | '3 lemon' | '3 orange' | '3 apple'<\/code><\/pre>\n<p>6. \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0434\u0436\u0435\u043d\u0435\u0440\u0438\u043a\u043e\u0432 (\u043e\u0431\u043e\u0431\u0449\u0435\u043d\u0438\u0439?) (<a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/generics.html#generic-constraints\" rel=\"noopener noreferrer nofollow\">Generic Constrains<\/a>)<\/p>\n<pre><code class=\"typescript\">type Length&lt;T extends { length: number }> = T[\"length\"];<\/code><\/pre>\n<p>7. \u041f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 (<a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/2\/functions.html#function-overloads\" rel=\"noopener noreferrer nofollow\">Function Overloads<\/a>)<\/p>\n<pre><code class=\"typescript\">function get&lt;O, K extends string>(obj: O, path: K): Get&lt;O, K>; function get(obj: Record&lt;string, unknown>, path: string): unknown {   \/\/ body }<\/code><\/pre>\n<p>\u0412\u0441\u0435\u043c \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435. \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043f\u043e\u0436\u0435\u043b\u0430\u043d\u0438\u044f, \u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438. \u0412\u0441\u0435\u043c \u0445\u043e\u0440\u043e\u0448\u0435\u0433\u043e \u0432\u0435\u0447\u0435\u0440\u0430 \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0445.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/808015\/\"> https:\/\/habr.com\/ru\/articles\/808015\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! ?<\/p>\n<blockquote>\n<p>\u26a0\ufe0f \u0412\u043e\u0437\u0440\u043e\u0436\u0434\u0430\u044e \u0441\u0442\u0430\u0442\u044c\u044e, \u043c\u043d\u043e\u044e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u0443\u044e \u0432 2021 \u043d\u0430 \u0425\u0430\u0431\u0440\u0435. \u0418\u0437 \u043d\u043e\u0432\u043e\u0433\u043e &#8212; \u043f\u043e\u0434\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c, \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043a\u0443\u0441\u043a\u0438 \u043a\u043e\u0434\u0430, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0410\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0442\u0443\u0442 &#8212; <a href=\"https:\/\/blog.beraliv.dev\/2021-03-26-typed-get\" rel=\"noopener noreferrer nofollow\">https:\/\/blog.beraliv.dev\/2021-03-26-typed-get<\/a>. \u041f\u0440\u0438\u044f\u0442\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f ?<\/p>\n<\/blockquote>\n<pre><code class=\"typescript\">type Get&lt;O, P> = never; \/\/ \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c  type Step1 = Get&lt;   { article: { author: \"Alexey Berezin\"; keywords: [\"typescript\"] } },   \"article.keywords.0\" >; type Step2 = Get&lt;   { author: \"Alexey Berezin\"; keywords: [\"typescript\"] },   \"keywords.0\" >; type Step3 = Get&lt;[\"typescript\"], \"0\">; type Step4 = Get&lt;\"typescript\", \"\">; type Result = \"typescript\";<\/code><\/pre>\n<p>\u0412 2021 \u0433\u043e\u0434\u0443 \u044f \u0440\u0430\u0441\u043a\u043e\u043f\u0430\u043b \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u0430\u0445 GitHub \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439\u00a0<a href=\"https:\/\/github.com\/type-challenges\/type-challenges\" rel=\"noopener noreferrer nofollow\">type-challenges<\/a>. \u0423 \u043c\u0435\u043d\u044f \u0435\u0441\u0442\u044c \u0446\u0435\u043b\u044b\u0439 \u0431\u043b\u043e\u0433, \u0433\u0434\u0435 \u044f \u0440\u0435\u0448\u0430\u044e \u0437\u0430\u0434\u0430\u0447\u043a\u0438 \u043e\u0442\u0442\u0443\u0434\u0430, \u043d\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u043f\u043e\u043f\u044b\u0442\u0430\u044e\u0441\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e\u00a0<code>Get<\/code>, \u043d\u043e \u0438 \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e \u043e\u0431\u0449\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043f\u043e\u043a\u0430\u0436\u0443 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 production.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0447\u0442\u0435\u043d\u0438\u044f \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u043f\u043e\u043d\u044f\u0442\u0438\u044f\u043c\u0438 \u0438\u0437 TypeScript, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u0435 \u0432 \u043a\u043e\u043d\u0435\u0446.<\/p>\n<h3>1. \u0411\u0430\u0437\u043e\u0432\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h3>\n<p><a href=\"https:\/\/github.com\/type-challenges\/type-challenges\/blob\/main\/questions\/00270-hard-typed-get\/README.md\" rel=\"noopener noreferrer nofollow\">\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u0447\u0435\u043b\u043b\u0435\u043d\u0434\u0436<\/a>\u00a0\u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 &#171;\u0441\u043b\u043e\u0436\u043d\u043e\u0435&#187;.<\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0438 \u043f\u0443\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0435 (\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0443\u0442\u0438 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u0438\/\u0438\u043b\u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0435). \u041e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0442\u0438\u043f \u0432\u0435\u0440\u043d\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u0442\u0438\u043f \u043f\u043e \u043f\u0443\u0442\u0438 \u0432 \u044d\u0442\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u0435.<\/p>\n<p>\u0422\u0430\u043a \u0441 \u0447\u0435\u0433\u043e \u0436\u0435 \u043d\u0430\u0447\u043d\u0435\u043c?<\/p>\n<h4>1.1. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u044e\u0447\u0435\u0439<\/h4>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0440\u0435\u0448\u0430\u043b\u0438 \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e JavaScript:<\/p>\n<pre><code class=\"javascript\">const get = (obj, path) => {   const keys = path.split(\".\");    return keys.reduce((currentObj, key) => currentObj[key], obj); };<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u00a0<code>keys.reduce<\/code>, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u043a\u043b\u044e\u0447\u0435\u0439. \u0412 JavaScript \u043d\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u00a0<code>split<\/code>. \u0412 TypeScript \u043d\u0430\u043c \u0442\u043e\u0436\u0435 \u043d\u0430\u0434\u043e \u043a\u0430\u043a-\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043b\u044e\u0447\u0435\u0439 \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f TypeScript 4.1, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u00a0<a href=\"https:\/\/devblogs.microsoft.com\/typescript\/announcing-typescript-4-1\/#template-literal-types\" rel=\"noopener noreferrer nofollow\">Template Literal types<\/a>. \u0421 \u0438\u0445 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0438 \u043c\u0435\u0436\u0434\u0443 \u043a\u043b\u044e\u0447\u0430\u043c\u0438. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0442\u0438\u043f\u00a0<code>Path<\/code>\u00a0\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434:<\/p>\n<pre><code class=\"typescript\">type Path&lt;T> = T extends `${infer Key}.${infer Rest}`   ? [Key, ...Path&lt;Rest>]   : [];<\/code><\/pre>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u043e\u0440\u043e\u0442\u043a\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043a\u0440\u044b\u0442\u0438\u044f \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u043c\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u0447\u0442\u043e \u0443\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u0441\u043b\u0443\u0447\u0430\u0439 \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c (\u0431\u0435\u0437 \u0442\u043e\u0447\u043a\u0438). \u0422\u0435\u0441\u0442\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0432\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBACghsAFgHgCoD4oF4qqhAD2AgDsATAZygAMASAbwEsSAzCAJygGkIQBfAHQNmbTgCUIFYH2oAoKFAD8UANo8QAGigCd8JMglT0AXXlQAXKtOyA9ACooAfWcvXL3JOBQAwnAqSnNyDHKDsbWUYAWzAAe3YveigAUQBHAFc4ABstJIJIAGMvPigWdhjIqAByAAFQSABafMQszNIAc0kbNOBGTIpK2Vk66Hy-AJwVM1yC4GRUjMzkPRRKmJIIeoBrXnqwBERK9C0VVfWtnb2kSuN0I6m8iEK59Kyl-eRKgCZzkAFLg6Oqi+P0qWkq-2utw09xmzwWb30lSQ7AgEAE21+EMBJ2RqNBVQx+PB+0hd2MQA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u043e\u0442 \u0441\u043b\u0443\u0447\u0430\u0439:<\/p>\n<pre><code class=\"typescript\">type Path&lt;T> = T extends `${infer Key}.${infer Rest}`   ? [Key, ...Path&lt;Rest>]   : T extends `${infer Key}`   ? [Key]   : [];<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043b\u0443\u0447\u0448\u0435. \u0422\u0435\u0441\u0442\u044b \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?ssl=5&amp;ssc=9&amp;pln=1&amp;pc=1#code\/C4TwDgpgBACghsAFgHgCoD4oF4qqhAD2AgDsATAZygAMASAbwEsSAzCAJygGkIQBfAHQNmbTgCUIFYH2oAoKFAD8UANo8QAGigCd8JMglT0AXXlQAXLnxFSlGsNYduvGWYXK1vUwoWWVp2QB6ACooAH0IyKjI3ElgKABhOApJcOj0sKhgwNlGAFswAHt2ePooAFEARwBXOAAbLXKCSABjeL4oFnZCvKgAcgABUEgAWhbEerrSAHNJQOrgRjqKPtlZYegW5NScFTMm1uBkKtq65D0UPsKSCBGAa14RsAREPvQtFSub+8fnpD7jOh3vtmhA2scavVzi9kH0AEw-EACP6vd6qeGIvpaPoogFAjQgw4Q07Q-R9JDsCAQAQPJG4tGfClUrH9WksnEvPHA4xAA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>.<\/p>\n<h4>1.2. Reducer \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043a\u043b\u044e\u0447\u0438, \u043c\u044b \u043d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c<code>keys.reduce<\/code>. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0442\u0438\u043f\u00a0<code>GetWithArray<\/code>\u00a0, \u0438\u043c\u0435\u044f \u0443\u0436\u0435 \u043f\u0443\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0430\u00a0<code>K<\/code><\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;O, K> = K extends [infer Key, ...infer Rest]   ? Key extends keyof O     ? GetWithArray&lt;O[Key], Rest>     : never   : never;<\/code><\/pre>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u044e:<\/p>\n<ol>\n<li>\n<p><code>K extends [infer Key, ...infer Rest]<\/code>\u00a0\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u043a\u043e\u0440\u0442\u0435\u0436\u0435<\/p>\n<\/li>\n<li>\n<p><code>Key extends keyof O<\/code>\u00a0\u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u00a0<code>O[Key]<\/code>\u00a0\u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0443\u0440\u043e\u0432\u043d\u044e \u043e\u0431\u044a\u0435\u043a\u0442\u0430<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u00a0(\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBA4hwHUCWwAWBBATpghiAPAPIA0UA0gHxQC85UEAHsBAHYAmAzlANpIsBmETOQghSAOkl9BwgEoQOwALoAoKFAD8IkPSatOUANaiA9vyiE16zbHjI0WXAULcyopaXmKKV9QC4oFggANyErAKDQzBUVAHoAKigAfRTUtNSoABUFYCgAYRwOBWT00qSoeNiVJABbMBNMXIBvKABRAEcAVxwAG1JWhkgAY1yAXyh+TBMaqAByAAFQSABaIdRentYAcwVYzuAkHo5ZmKXobMVCACMAKwgRmigmqwPgTYCAAwBlIamenquOGEQ06immSA4OAOJhYHysbChEE+ACYAAwARgAHMt0ajlqiACxw9Q4faoBoBZ7WQI4GpIqAfdCbBiiKAAISEEAAXnxidYeiYhlCkDDKb5rEMUCBPgBZTosJBrPnqUZWVWqlRnKBCopcWjcKwDYbAfAdbo9fBwRAoDDYPD4C7Aa53EakbizV6bWZKCikb6-Ez-QHA0HAcGQ6Gwii+w2De4ms29S12G2Oe2O53xt2zBHMb2+hlorE4vGEj7R4ix42mrpJq32W1OB05TOung5hS-JBgSP50iRIQVqvxmvm5PWhx2ggZ25Z9uktANWakWYsWkQPsMpmMVkczDc3lD9RGkeJi311NT5uXWdt90L8mYZdzAVC3sryWgTcfOUKpVHto4xGUc6xTScmxnF1gGzB8lw-IE2GfVdOhqK4hE3AdMCHJQgA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>). \u041e\u043f\u044f\u0442\u044c \u043c\u044b \u0437\u0430\u0431\u044b\u043b\u0438 \u0441\u043b\u0443\u0447\u0430\u0439, \u043f\u0440\u0430\u0432\u0434\u0430 \u0443\u0436\u0435 \u043a\u043e\u0433\u0434\u0430 \u0443 \u043d\u0430\u0441 \u043f\u0443\u0441\u0442\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432. \u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u0434 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;O, K> = K extends []   ? O   : K extends [infer Key, ...infer Rest]   ? Key extends keyof O     ? GetWithArray&lt;O[Key], Rest>     : never   : never;<\/code><\/pre>\n<p>\u0424\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0432<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBA4hwHUCWwAWBBATpghiAPAPIA0UA0gHxQC85UEAHsBAHYAmAzlANoC6AUFCgB+KIUFQAXHUbN2XbkhYAzCJnIQQpAHS6lq9QCUIHYAKFDRZTfSatOUANaaA9srESLI2PGRosuASE3NYgvKTGphSeFtIsEABuajFxicn8APQAVFAA+vkFhQVQAComwFAAwjgcJnlFDblQWRn8SAC2YC6YFQDeUACiAI4ArjgANqQDDJAAxhUAvlDKmC7tUADkAAKgkAC0s6gT46wA5iYZI8BI4xwb-Py70GWmhABGAFYQ8zRQvRLXYAnaQAAwAyrNVuNxm8cOpZiNTGskBwcNcXCwQRI2GiIKCAEwABgAjAAOPbEwl7QkAFixQhwV1Q3Wk-y8LBw7TxUBB6BODBsACE1BAAF5KekWcYuWZopAY1kxISzFAgUEAWRGLCQh0lQgWEgNBse4GgstqXFo3Ak0zmwHwwzG43wcEQKAw2Dw+BewHeX3mpG4G0BJw2vAopHBkJc0Nh8MRwGRqPRmIoEZtM2+9sdExdvndAS9Pr9WcDGxxzDDEZ5RLJFKptJBaeIGbtDtGuddfg9gW95RLAZ45ZMkKQYBTVdI8SSmGbraz7adebd-k9BGLn1LQ8ZaG6G1IGw5XMnPL5jCFIvFqfTQltC5zzq7BbXfdem8HQZ3zMw+820tlE4HiqoAniCmrarqc63pm8yLp2+arr2G7+sAZZfnuQFwmwv6HiM7RvGoJ7Tmoc68EAA\" rel=\"noopener noreferrer nofollow\">\u00a0Playground<\/a><\/p>\n<h4>1.3. \u0412\u0441\u0435 \u0432\u043c\u0435\u0441\u0442\u0435<\/h4>\n<pre><code class=\"typescript\">type Get&lt;O, P> = GetWithArray&lt;O, Path&lt;P>>;<\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u0438 \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u0442\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f:\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBACghsAFgHgCoD4oF4qqhAD2AgDsATAZygAMASAbwEsSAzCAJygGkIQBfAHQNmbTgCUIFYH2oAoKFAD8UANo8QAGigCd8JMglT0AXXlQAXLnxFSlGsNYduvGWeVrephZZWnZoSCgAcQhgAHVGJABBdnY4EGQAeS0uTBwua2JyKl83KESzSwzCLLsVESd1LR0BCvFJYC8FJWcQTNsqAGteAHsWfLNmlpDwyMQYuITEjxBjLUNgdEHmyxIIADcOZdWNrf9waBGkrRg04NCI6Nj449gEFFOl2QB6ACooAH0v75-v3AaoABhOAUSSfX4Qj5QV7PWSMAC2YB67GAUHoUAAogBHACucAANloMQRIABjVF8KAsdg9eFQADkAAEAhAALSkxAE-GkADmkmeOOAjHxFHpsn2gVQDUSACMAFYQcnYNFmIXAbmWagAZVJNPx+JlcE4pJxUlpjAoCEYPRIcgUZAQEE1ACYAAwARgAHKz3a7Wa6ACx2qBwQWIZGWejLEhweFOmhRbkEXhQABCHAgAC9mMGFPieqSrTbI8sFKTIiBNQBZHEkRgc3NQPhmZvNiXQQugqg4FRmYlk4DIbF4-HII5SqSyhXkrT0tXc+noLTa3U9fWG42m4Dmy1Cm3UdBLvskxWD4cEsehNDS+Wn2cO4iL5dur0+v2Bg9HhT909D3EX8cb2nYB70kXVGDAPcSCfKA1k2dhDw0Y8Bz-EdL0HCdgCnO8GVDJBkQEGM4xg6hE0IFN03YLMc0Q5Df3PUdAMnW8Z1wsMCPzQsoIEctQBIms6wbWjvxPclUIAq9MOw1j6Tw8N2B4o0yEInF4RlDgYLgjhaOMIA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>. \u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438.<\/p>\n<h3>2. \u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0443\u0442\u0438<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0448\u044c \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 production, \u0442\u0435\u0431\u0435 \u0438\u043d\u043e\u0433\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0438\u043b\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442, \u043d\u043e \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u00a0<code>?<\/code>\u00a0,\u00a0<code>null<\/code>\u00a0\u0438\u043b\u0438<code>undefined<\/code>.<\/p>\n<p>\u0412\u043e\u0437\u044c\u043c\u0435\u043c \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438 \u043f\u043e\u043a\u0440\u043e\u0435\u043c \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435:\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBACghsAFgHgCoD4oF4qqhAD2AgDsATAZygAMASAbwEsSAzCAJygGkIQBfAHQNmbTgCUIFYH2oAoKFAD8UANo8QAGigCd8JMglT0AXXlQAXLnxFSlGsNYduvGWeVrephZZWnZoSCgAcQhgAHVGJABBdnY4EGQAeS0uTBwua2JyKl83KESzSwzCLLsVESd1LR0BCvFJYC8FJWcQTNsqAGteAHsWfLNmlpDwyMQYuITEjxBjLUNgdEHmyxIIADcOZdWNrf9waBGkrRg04NCI6Nj449gEFFOl2QB6ACooAH0v75-v3AaoABhOAUSSfX4Qj5QV7PWSMAC2YB67GAUHoUAAogBHACucAANloMQRIABjVF8KAsdg9eFQADkAAEAhAALSkxAE-GkADmkmeOOAjHxFHpsn2gVQDUSACMAFYQcnYNFmIXAbmWagAZVJNPx+JlcE4pJxUlpjAoCEYPRIcgUZAQEE1ACYAAwARgAHKz3a7Wa6ACx2qBwQWIZGWejLEhweFOmhRbkEXhQABCHAgAC9mMGFPieqSrTbI8sFKTIiBNQBZHEkRgc3NQPhmZvNiXQGA0sg48nWkiyhVKnBR+2SXWMMBCm2KSxSdjMHkAblVkQ1UDnC+X9sds+A85IS7MoaQyJnKqGMbju-3h6G+cLU5IZ5HQyg5dA183y2bClb4pZb4gmCOAqGYbxQMQUiAaCVAwmYxJksAyDYni+LIEcUpSAOirAFo9Jqty9LoFo2q6j0+qGsaprAOalqPtQ6DEfBJI4chuIEuhoRoNK8o4XhDrEERJFul6Pp+oGDFMQoCGsShHEYTxg64QyZBjvOk59kJUBrJs7CMRozGIWxqGcUhmHANh5J4ce4bsAIl4QFp1CJoQKbpuwWY5vphmyexaEKVhvFWQyNnIgI95FiQAjviATk1nWDbedJLHksZ8lceZlnKfSoV2YW7BkPZOLwjKHBaTpHBJVA4FgF2PaPtBYJwclRlyf5XGdj03a9jaWV4QRjnEeue4LlVMmpW1pnIJ13WPn1KmOlpG4HmNKVIZNRwzfVfbzfSqkUOOGk2ktI0HlAAA+UC1qpLDMBAZCra1flTVtPX9kF2W5fZsaDVoy08hdV3kBAt1rA9UmYmtaXtUhr1zR91lhmFEWPtFFYnTegPXSDd3gwZLW+SZm11W9u1fflhUkMVpXsFp2Og-d3nGEAA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>. \u041a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, TypeScript \u0440\u0443\u0433\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u0430. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u043e\u0437\u044c\u043c\u0435\u043c \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u0440\u0438\u043c\u0435\u0440 \u0438 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e \u043f\u0440\u043e\u0439\u0434\u0435\u043c\u0441\u044f:<\/p>\n<pre><code class=\"typescript\">type ProductionObject = {   description?: string;   title: string;   date: string;   author?: {     name: string;     location?: {       city: string;     };   }; };  type Step1 = Get&lt;ProductionObject, \"author.name\">; type Step2 = Get&lt;   | {       name: string;       location?:         | {             city: string;           }         | undefined;     }   | undefined,   \"name\" >; type Step3 = Get&lt;never, \"\">; type Result = never; \/\/ \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c `string | undefined`<\/code><\/pre>\n<p>\u0422\u0435\u043a\u0443\u0449\u0435\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u044c \u043a\u043b\u044e\u0447 \u0438\u0437 \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c\u00a0<code>undefined<\/code>\u00a0or\u00a0<code>null<\/code>. \u041f\u043e\u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f \u044d\u0442\u043e \u0440\u0435\u0448\u0438\u0442\u044c.<\/p>\n<h4>2.1. \u0423\u0434\u0430\u043b\u044f\u0435\u043c undefined, null \u0438\u043b\u0438 \u043e\u0431\u0430 \u0442\u0438\u043f\u0430 \u0441\u0440\u0430\u0437\u0443<\/h4>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c 3 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0442\u0438\u043f\u0430:<\/p>\n<pre><code class=\"typescript\">type FilterUndefined&lt;T> = T extends undefined ? never : T;  type FilterNull&lt;T> = T extends null ? never : T;  type FilterUndefinedAndNull&lt;T> = FilterUndefined&lt;FilterNull&lt;T>>;<\/code><\/pre>\n<p>\u041c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e\u00a0<code>undefined<\/code>\u00a0\u0438\/\u0438\u043b\u0438\u00a0<code>null<\/code>\u00a0\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e union type, \u0438 \u0435\u0441\u043b\u0438 \u0442\u0430\u043a, \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0438\u0445 \u0438\u0437 \u043d\u0435\u0433\u043e. \u042d\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 &#171;\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439&#187; \u0447\u0430\u0441\u0442\u044c\u044e.<\/p>\n<p>\u0422\u0435\u0441\u0442\u044b, \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u0432\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBAYglgG2BATgVQHYBMIDM4YRYA8AKgHxQC8UpUEAHstgM5QCu2eBRUA-FEIA3VFABctAFCTQkWImQoAcuwQIylGnUbMsbDKoT9BEESnFSZ4aPCSpMOfISwBBbCrUbq8u+i5OiYltFD3UKcmkAegAqKAB9BMSkxNoIFmAoAGEAQxY0+OTCuKhoyMk4AFswAHsUDIBvKABRAEd2bIQAGmaGSABjDIBfKFwUaoqoAHIAAVkIAFo+gAsOhAgMAHM0yPZgRBZJ6TmoPtz8mgBtSSge-uBiVvb1YPt-Hld3Q2IARigAHygACZ-lAAMwgziOd7kbq-AHAgGg8gw663CADB5tDpBBSvKHONxYULESbVQiTEGTYAAd2qFIBVKWKAgEHpgkMMKmZNZlJpdN5TJZk2RnVRTV66Puj2xLz8+KIhOJcKmfLZBjUELezk5yqptOFKJu4rumKeON8Dm4BM+nkhVqInOEqBFYolGOlz1xcvtHyJX3VCEdpmdhrR7qxnotWoVNvUdoCWBBAaDZhdAF0gA\" rel=\"noopener noreferrer nofollow\">Playground<\/a><\/p>\n<h4>2.2. \u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c reducer<\/h4>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u0432\u043e\u0442 \u044d\u0442\u0443 \u0432\u0435\u0442\u043a\u0443\u00a0<code>GetWithArray<\/code>:<\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;O, K> = K extends []   ? O   : K extends [infer Key, ...infer Rest]   ? Key extends keyof O     ? GetWithArray&lt;O[Key], Rest>     : never \/\/ &lt;= \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0437\u0434\u0435\u0441\u044c ?   : never;<\/code><\/pre>\n<ol>\n<li>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u043a\u043b\u044e\u0447 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u0441\u00a0<code>undefined<\/code>\u00a0\u0438\/\u0438\u043b\u0438\u00a0<code>null<\/code><\/p>\n<\/li>\n<li>\n<p>\u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0433\u043e \u043d\u0435\u0442 (\u0442\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u00a0<code>undefined<\/code>)<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"typescript\">type GetWithArray&lt;O, K> = K extends []   ? O   : K extends [infer Key, ...infer Rest]   ? Key extends keyof O     ? GetWithArray&lt;O[Key], Rest>     : Key extends keyof FilterUndefinedAndNull&lt;O>     ? GetWithArray&lt;FilterUndefinedAndNull&lt;O>[Key], Rest> | undefined     : undefined   : never;<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0437\u0434\u0435\u0441\u044c \u0442\u0435\u0441\u0442\u044b \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u0442\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e (\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBAYglgG2BATgVQHYBMIDM4YRYA8AKgHxQC8UpUEAHstgM5QCu2eBRUA-FEIA3VFABctAFCTQkWImQoAcuwQIylGnUbMsbDKoT9BEESnFSZ4aPCSpMOfISwBBbCrUbq8u+i5OiYltFD3UKcmlZaABxCGAAdThgAAsXFBQAQxBiAHkAGigAaU0i+iYIVigAbQBdSShjHPqLQrLdNiqCXFFCiBACgDohrtEAJQgWYDqGhoFekDaKvSgAaz6Ae1woJpmZgViEpNT0rNyq+ZqC8cmI3YaJecXKtZBNn0UHbmc3LFDc27usygB0SKTSmWywXs-h4rnchn+5z6lyg12AlAAPhwYc5moCJJxHLC8RZhKhpAB6ABUUAA+vSGYyGbQJsAoABhDIsCZ0pl82lQKkUyRwAC2YHWKDZAG8oABRACO7AyCAKcoYkAAxmyAL5QXAodaiqAAcgAAlEALSa5IqhAVADmEwp7GAiBYJsi1igAAVDVh2Nq4OsMDkAEYAKwg2u80uaOBYmpQcDAbpDfAkk2TGAdzTdwHtmeA2dzDSwGWQRZLzQyruSkozUDjuwwGVFECrBFLMwQ601FeDGEbzbumqSIE7OZJOuaM5nVjk-e5bBoVWa6q1wGIiuV6hBR3Bpz96wDQZD4aj2oKVRN+ftJpq5AKWa75Cf6410a3O5VxH3YJObJj1PNNQ0jL9rxNctkAfJ8oBfHM3zyD9N23JVf3-Y4IWIYDA1Ai8IOqKCJiTFNQNg59iy7KAsUJL4iCQlCvzQ3c-ziUEsKPf08MHAiryI2sUklE0ChNVt2wo+CqJzGjsSJZxGIaDdmJ-Pd2IPQCcO4s8wMvYBIME+sUBE01e37cjRLHUBJIQh1ZLogIsEU+VP21FiMPUgDsNwnS+P0gS62EyyMhQLATLE9hRTDVBJIc2FGJqIA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>).<\/p>\n<h2>3. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u0443\u0442\u0438 \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0438<\/h2>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0431\u0435\u0440\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c \u0438 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c:<\/p>\n<pre><code class=\"typescript\">type ProductionObject = {   posts: {     title: string;     description?: string;     poster?: string;     html: string;   }[]; };  type Step1 = Get&lt;ProductionObject, \"posts.0\">; type Step2 = Get&lt;   {     title: string;     description?: string;     poster?: string;     html: string;   }[],   \"0\" >; type Step3 = Get&lt;undefined, \"\">; type Result = undefined; \/\/ ? \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c `string | undefined`<\/code><\/pre>\n<p>\u0412 JavaScript \u043c\u044b \u0431\u044b \u0445\u043e\u0434\u0438\u043b\u0438 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u043c:<\/p>\n<pre><code class=\"javascript\">const get = (arr, path) => {   const keys = path.split(\".\");    return keys.reduce((currentArr, key) => currentArr[key], arr); };<\/code><\/pre>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043a\u043b\u044e\u0447 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c\u00a0<code>string<\/code>\u00a0\u0438\u043b\u0438\u00a0<code>number<\/code>,\u00a0<code>Path<\/code>\u00a0\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u044b\u043c:<\/p>\n<pre><code class=\"typescript\">type Path&lt;T> = T extends `${infer Key}.${infer Rest}`   ? [Key, ...Path&lt;Rest>]   : T extends `${infer Key}`   ? [Key]   : [];<\/code><\/pre>\n<h4>3.1. Reducer \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430<\/h4>\n<p>\u041a\u0430\u043a \u0438 \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u00a0<code>keys.reduce<\/code>\u00a0. \u0414\u043b\u044f TypeScript \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u00a0<code>GetWithArray<\/code>\u00a0. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432, \u0430 \u0437\u0430\u0442\u0435\u043c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438\u00a0<code>GetWithArray<\/code>\u00a0\u0432 \u043e\u0434\u043d\u043e.<\/p>\n<p>\u0421\u043f\u0435\u0440\u0432\u0430 \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0430. \u0412\u043e\u0437\u044c\u043c\u0435\u043c\u00a0<code>A<\/code>\u00a0\u0432\u043c\u0435\u0441\u0442\u043e\u00a0<code>O<\/code>\u00a0\u043f\u043e \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c:<\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;A, K> = K extends []   ? A   : K extends [infer Key, ...infer Rest]   ? Key extends keyof A     ? GetWithArray&lt;A[Key], Rest>     : never   : never;<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBA4hwHUCWwAWBBATpghiAPOgDRQDSAfFALxlQQAewEAdgCYDOUA2gLoBQUKAH4o6AVABctBkzacuSZgDMImMhBAkAdDsUq1AJQjtg-QYJGkNdRiw5QA1hoD2S0ePPDY8ZGiy4CdC4rEB4SIxNyD3MpZggAN1Vo2ISkvgB6ACooAH08-IL8qAAVY2AoAGEcdmNcwvqcqEz0viQAWzBnTHKAbygAUQBHAFccABsSfvpIAGNygF8oJUxnNqgAcgABUEgAWhnUcbGWAHNjdOHgJDH2db4+HehSkwB5ACMAKwg56m5xdPSUAADOIAAYAZRmKzGYzeODUM2GJlWSHYOCuzmYoKI-0BAEYwQAmIF4gAcuzxQN2QIALNjcVBCeIuNEAYytCDPCZMIoTjjPGzCVoCZ4ABTc3lQAA+UGYwzab1UAEpePzzIKtEzPJgIDhWJixiBZfLFZheOJ+DwANz3R5QGbVWo0FmCKazYD4IajMb4OCIFAYbB4fDPYDvL5zEhcdZA9Y8cgkCFQ5wwuEIpHAFFojFY8gJ8Ru74er3jX0+AP+YOh8NFqPrPFxhNQUHEskUqm00F5tWFuaekalv2+QMBENlGuR7jrQnrEgxxskCXME7dgvTIv971l-1+IMEaufWtTmdzhtz2PxxfAHnL6XGhWqO-DNgQJSKCCsVeu9d9ks+ocVnuY6vIek7RieGwQdOC73qaT4vm+cSfvm37upug7lruo4HhGwB1gAzDBz6sK+77ITiPBAA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>, \u043c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438:<\/p>\n<p>1. \u041c\u0430\u0441\u0441\u0438\u0432\u044b \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u043a\u043b\u044e\u0447\u0435\u0439 \u0441 \u0442\u0438\u043f\u043e\u043c \u00a0<code>string<\/code>\u00a0:<\/p>\n<pre><code class=\"typescript\">type Step1 = GetWithArray&lt;string[], \"1\">; type Step2 = \"1\" extends keyof string[] ? string[][\"1\"] : never; type Result = never; \/\/ ? \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c `string | undefined`<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c\u00a0<code>'1' extends keyof string[]<\/code>\u00a0\u0432\u0441\u0435\u0433\u0434\u0430 \u043b\u043e\u0436\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u00a0<code>never<\/code>.<\/p>\n<p>2. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u043c\u00a0<code>readonly<\/code><\/p>\n<pre><code class=\"typescript\">type Step1 = GetWithArray&lt;readonly string[], \"1\">; type Step2 = \"1\" extends keyof (readonly string[])   ? (readonly string[])[\"1\"]   : never; type Result = never; \/\/ ? \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c `string | undefined`<\/code><\/pre>\n<p>3. \u041a\u043e\u0440\u0442\u0435\u0436\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440\u00a0<code>[0, 1, 2]<\/code>) \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u00a0<code>never<\/code>\u00a0\u0432\u043c\u0435\u0441\u0442\u043e\u00a0<code>undefined<\/code>:<\/p>\n<pre><code class=\"typescript\">type Step1 = GetWithArray&lt;[0, 1, 2], \"3\">; type Step2 = \"3\" extends keyof [0, 1, 2] ? [0, 1, 2][\"3\"] : never; type Result = never; \/\/ ? \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c `undefined`<\/code><\/pre>\n<p>\u041f\u043e\u0439\u0434\u0435\u043c \u0447\u0438\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e.<\/p>\n<h4>3.2. \u0412\u044b\u0432\u043e\u0434\u0438\u043c T | undefined<\/h4>\n<pre><code class=\"typescript\">type GetWithArray&lt;A, K> = K extends []   ? A   : K extends [infer Key, ...infer Rest]   ? Key extends keyof A     ? GetWithArray&lt;A[Key], Rest>     : never \/\/ &lt;= \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0437\u0434\u0435\u0441\u044c ?   : never;<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u00a0<code>T | undefined<\/code>\u00a0\u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 (\u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0440\u0438 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0438 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443 \u043c\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u043c, \u0435\u0441\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438\u043b\u0438 \u043d\u0435\u0442), \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u00a0<code>T<\/code>:<\/p>\n<pre><code class=\"typescript\">type GetWithArray&lt;A, K> = K extends []   ? A   : K extends [infer Key, ...infer Rest]   ? Key extends keyof A     ? GetWithArray&lt;A[Key], Rest>     : A extends readonly (infer T)[]     ? GetWithArray&lt;T | undefined, Rest>     : never   : never;<\/code><\/pre>\n<p>\u042f \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u00a0<code>A extends readonly (infer T)[]<\/code>\u00a0, \u0442.\u043a. \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 (\u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u00a0<code>readonly<\/code>) \u044d\u0442\u043e \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u043d\u043e.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0447\u0438\u043d\u0438\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436\u0438. \u041f\u0440\u0438\u043c\u0435\u0440 \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432\u00a0<a href=\"https:\/\/www.typescriptlang.org\/play?#code\/C4TwDgpgBA4hwHUCWwAWBBATpghiAPOgDRQDSAfFALxlQQAewEAdgCYDOUA2gLoBQUKAH4o6AVABctBkzacuSZgDMImMhBAkAdDsUq1AJQjtg-QYJGkNdRiw5QA1hoD2S0ePPDY8ZGiy4CdC4rEB4SIxNyD3MpdBtZe0wIHFZnZgAbECgACj1VKAAVAEpeaM8ROEQUDGw8fAKoAB8oAFc2CCVFCFZw42Aoz08pZggAN1Vo4bGJvgB6ACooAH0V1bXVwr6oAGEcdmNl9aOlqHnZviQAWzBnTGAoAG8oAFEARxacdJJn+kgAY3uAF8oEpMM5LlAAOQAAVAkAAtH9UJ90iwAObGWYtYBIdLsSF8Phw6AFPoAeQARgArCAA6jccSzWZQAAM4gABgBlP5g9LpCk4NR-FomcFIdg4HFpdlERnMgCMHIATCz5QAOeHylnwlkAFhlcqgSvEXGiTKNWjZnhMmEUaNlnnNSq0is82RtdqaUGYLUuFNUJTCZuZzuNniSKTSmW9vv9mFKgn4PAA3ITiVA-nsDjRTYIfv9gPg3h90vhKr4agF6uTqbTgCQuJCWZCeOQSFyec4+QKhSLgGKJVLmOzyG3xPm60X3p8yz5qv46qSTJSaQCG5D5S221B2Sr1ZrtXqR2O879J8WZ+X57UCEvgCu6+ulZCSE2tyQPcw0aOHS8zwCpxLWcqj8G9q2XWs124SFn1fTdX2bVsP2AW0vy9H0-XyZo2lYDoulYH9x3-QsL1LK9QKrO8HygxtYKhOiYPfGNMLUbD2k6EYCJPP8C0Ay85woxca1XetoIAZiYnC8M4wieCAA\" rel=\"noopener noreferrer nofollow\">Playground<\/a>.<\/p>\n<h4>3.3. \u041a\u043e\u0440\u0442\u0435\u0436\u0438<\/h4>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0431\u043e\u0431\u0449\u0430\u044e\u0449\u0438\u0439 \u0442\u0438\u043f, \u043a\u0430\u043a \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 (\u043d\u0443 \u0438 \u0435\u0449\u0435\u00a0<code>undefined<\/code>\u00a0\u0432 \u043f\u0440\u0438\u0434\u0430\u0447\u0443)<\/p>\n<pre><code class=\"typescript\">type Step1 = GetWithArray&lt;[0, 1, 2], \"3\">; type Step2 = \"3\" extends keyof [0, 1, 2] \/\/ &lt;= false   ? [0, 1, 2][\"3\"]   : [0, 1, 2] extends (infer T)[] \/\/ &lt;= true   ? T | undefined   : [0, 1, 2] extends readonly (infer T)[]   ? T | undefined   : never;  type Result = 0 | 1 | 2 | undefined; \/\/ ? \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c `undefined`<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u0441 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439, \u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0443 \u0441\u00a0<code>extends<\/code>\u00a0\u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 (\u043d\u0430\u0437\u043e\u0432\u0435\u043c \u044d\u0442\u0443 \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0443\u00a0<code>ExtendsTable<\/code>) \u0438 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u0442\u0438\u043f, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0438:<\/p>\n<pre><code class=\"typescript\">type ExtendsTableRow&lt;T extends any[], E extends any> = {   [K in keyof T]: E extends T[K] ? true : false; };  type ExtendsTable&lt;T extends any[]> = {   [K in keyof T]: ExtendsTableRow&lt;T, T[K]>; };<\/code><\/pre>\n<p>\u0412\u043e\u0437\u044c\u043c\u0435\u043c 4 \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u0430:<\/p>\n<ol>\n<li>\n<p><code>[0]<\/code><\/p>\n<\/li>\n<li>\n<p><code>number[]<\/code><\/p>\n<\/li>\n<li>\n<p><code>readonly number[]<\/code><\/p>\n<\/li>\n<li>\n<p><code>any[]<\/code><\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"typescript\">type Result = ExtendsTable&lt;[[0], number[], readonly number[], any[]]&gt;;<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430\u0440\u0438\u0441\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"316\" width=\"316\">\n<p align=\"left\">\n<\/td>\n<td data-colwidth=\"76\" width=\"76\">\n<p align=\"left\"><code>[0]<\/code><\/p>\n<\/td>\n<td data-colwidth=\"116\" width=\"116\">\n<p align=\"left\"><code>number[]<\/code><\/p>\n<\/td>\n<td data-colwidth=\"144\" width=\"144\">\n<p align=\"left\"><code>readonly number[]<\/code><\/p>\n<\/td>\n<td>\n<p align=\"left\"><code>any[]<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"316\" width=\"316\">\n<p align=\"left\"><code>[0]<\/code><\/p>\n<\/td>\n<td data-colwidth=\"76\" width=\"76\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td data-colwidth=\"116\" width=\"116\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td data-colwidth=\"144\" width=\"144\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"316\" width=\"316\">\n<p align=\"left\"><code>number[]<\/code><\/p>\n<\/td>\n<td data-colwidth=\"76\" width=\"76\">\n<p align=\"left\">\u200b-<\/p>\n<\/td>\n<td data-colwidth=\"116\" width=\"116\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td data-colwidth=\"144\" width=\"144\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"316\" width=\"316\">\n<p align=\"left\"><code>readonly number[]<\/code><\/p>\n<\/td>\n<td data-colwidth=\"76\" width=\"76\">\n<p align=\"left\">\u200b-<\/p>\n<\/td>\n<td data-colwidth=\"116\" width=\"116\">\n<p align=\"left\">\u200b-<\/p>\n<\/td>\n<td data-colwidth=\"144\" width=\"144\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u200b-<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"316\" width=\"316\">\n<p align=\"left\"><code>any[]<\/code><\/p>\n<\/td>\n<td data-colwidth=\"76\" width=\"76\">\n<p align=\"left\">\u200b-<\/p>\n<\/td>\n<td data-colwidth=\"116\" width=\"116\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td data-colwidth=\"144\" width=\"144\">\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u200b+<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/th>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0430 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0438 \u0437\u043d\u0430\u043a \u043f\u043b\u044e\u0441\u0430 \u200b&#187;+&#187;, \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u0441\u0442\u0440\u043e\u0447\u043a\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u0430 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u043c. \u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432:<\/p>\n<ul>\n<li>\n<p><code>[0] extends [0]<\/code><\/p>\n<\/li>\n<li>\n<p><code>number[] extends readonly number[]<\/code><\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0435\u0441\u043b\u0438 \u043d\u0430<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-373753","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/373753","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=373753"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/373753\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=373753"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=373753"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=373753"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}