Mundarija (35)
- Bu darsda
- 1. Nega bu kerak?
- 2. .tsx fayl va props turi
- 2.1 .tsx — JSX bor TypeScript fayli
- 2.2 Props turi — oddiy obyekt turi
- 2.3 Omborchi ishda: uch xil xato
- 2.4 type yoki interface?
- 3. Ixtiyoriy props va standart qiymat
- 3.1 ? va standart qiymat
- 3.2 exactOptionalPropertyTypes tuzog'i
- 3.3 readonly props
- 4. children turlari
- 4.1 ReactNode — eng keng tur
- 4.2 children turida bo'lmasa
- 4.3 ReactElement — faqat element
- 4.4 JSX.Element va qaytish turi
- 4.5 PropsWithChildren
- 5. React.FC munozarasi
- 5.1 Ikki yozuv
- 5.2 Tarix: yashirin children
- 5.3 Bugungi tanlov
- 6. Props turini qayta ishlatish
- 7. Vazifalar qadami: TS qadami boshlanadi
- 7.1 Besh dars — bitta branch
- 7.2 Uch yangi bayroq — o'lchab qo'shildi
- 7.3 strictTypeChecked — 70 topilma, 0 xato
- 8. Ko'p uchraydigan xatolar
- 9. Mashqlar
- 1-mashq (oson): qaysi tur?
- 2-mashq (o'rta): kartaga tur yozing
- 3-mashq (qiyin): FC kodni ko'chirish
- 4-mashq: Vazifalar qadami
- 10. Real ishda
- Xulosa
- Manbalar
React + TS I: props va children turlari — type, ReactNode va React.FC munozarasi
Qisqacha: React komponentining props'i — oddiy obyekt, shuning uchun uning turi ham oddiy obyekt turi:
type MenuCardProps = { name: string; price: number }. TypeScript har<MenuCard … />ni shu tur bilan solishtiradi: yetishmagan, ortiqcha yoki noto'g'ri turdagi prop — kompilyatsiyada xato. Komponent bolalari (children) uchun eng keng tur —ReactNode(satr, son, element,null, massiv), torroq kerak bo'lsa —ReactElement.React.FCishlaydi, lekin zamonaviy kodda props'ni to'g'ridan-to'g'ri turlash afzal: soddaroq va generic bilan ham ishlaydi.
Bu darsda
- Props turini
typeyokiinterfacebilan yozasiz va tsc xabarlarini (TS2322,TS2741) o'qiysiz. - Ixtiyoriy props, standart qiymat va
exactOptionalPropertyTypestuzog'ini ko'rasiz. childrenuchun to'g'ri turni tanlaysiz:ReactNode,ReactElementyokiPropsWithChildren.React.FChaqidagi munozarani tushuntira olasiz va negavazifalarda u yo'qligini bilasiz.vazifalarda TS qadamini boshlaysiz: tsconfig'ga uchta bayroq va ikkita o'lchangan, lekin kirmagan variant.
Oldin bilishingiz kerak: children va kompozitsiya, Props, Obyekt turlari, type va interface.
1. Nega bu kerak?
Dizayn tizimi asoslari darsida «Bahor» menyusi uchun kichik komponentlar to'plami paydo bo'ldi. Endi ularni boshqalar ham ishlatadi. Sardor yangi sahifaga taom kartasini qo'ydi:
<MenuCard name="Osh" pirce={35000} />price o'rniga pirce — bitta harf adashgan. JavaScript'da hech qanday xato chiqmaydi. Komponent price ni oladi, u esa undefined. Ekranda "Osh — so'm" chiqadi, narx yo'q. Jasur aka buni faqat mijoz shikoyat qilganda ko'radi.
Hayotiy o'xshatish: oshxonaga kelgan mahsulot yuk xati bilan keladi. Omborchi xatga qarab tekshiradi: "go'sht 10 kg, sabzi 5 kg". Biror narsa yetishmasa yoki ortiqcha bo'lsa — mahsulot qabul qilinmaguncha aniqlanadi, qozonga tushgandan keyin emas. Props turi — komponentning yuk xati. TypeScript esa omborchi: har <MenuCard … /> ni xat bilan solishtiradi.
TypeScript qismida turlarni oddiy funksiyalarga yozgan edingiz. 17-qismda vazifalar ning har komponenti .tsx da edi va props turlarini ko'rdingiz. Bu darsda shu bilimni tartibga solamiz va chuqurlashtiramiz.
2. .tsx fayl va props turi
2.1 .tsx — JSX bor TypeScript fayli
TypeScript JSX'ni faqat .tsx kengaytmali faylda tushunadi. Oddiy .ts faylda <p> — tur o'zgartirish (type assertion) sintaksisining eski shakliga o'xshaydi va tahlilchi adashadi:
const el = <p>Salom</p>;Xato:
TS1161: Unterminated regular expression literal."Tugallanmagan muntazam ifoda." Xabar g'alati tuyulishi tabiiy: .ts faylda tsc </p> dagi / ni regex boshi deb o'qidi. Qoida oddiy: komponent yoki JSX bor fayl — .tsx. Faqat mantiq (reducer, hisob, tekshiruv) — .ts. vazifalar da aynan shunday: reducer.ts, amallar.ts va App.tsx, Tugma.tsx.
2.2 Props turi — oddiy obyekt turi
Komponent — funksiya, props esa uning yagona argumenti, obyekt. Demak props turi — obyekt turi:
type MenuCardProps = {
name: string;
price: number;
};
function MenuCard({ name, price }: MenuCardProps) {
return (
<p>
{name} — {price} so'm
</p>
);
}
export default function App() {
return (
<div>
<MenuCard name="Osh" price={35000} />
<MenuCard name="Manti" price={30000} />
</div>
);
}Ekranda:
Osh — 35000 so'm
Manti — 30000 so'mUch narsaga qarang:
- Nom. Tur nomi — komponent nomi +
Props. Bu umumiy kelishuv: faylni ochgan har kim darhol tushunadi. - Destrukturizatsiya.
{ name, price }: MenuCardProps— tur butun obyektga yoziladi, bo'laklarga emas. - Qaytish turi yozilmagan. TypeScript uni o'zi chiqaradi (inference). Komponent JSX qaytarsa — tur ham to'g'ri.
2.3 Omborchi ishda: uch xil xato
Endi Sardorning xatosini va yana ikkitasini bitta faylda ko'ramiz:
type MenuCardProps = { name: string; price: number };
function MenuCard({ name, price }: MenuCardProps) {
return <p>{name} — {price} so'm</p>;
}
export default function App() {
return (
<div>
<MenuCard name="Osh" pirce={35000} />
<MenuCard name="Manti" />
<MenuCard name="Lag'mon" price="28000" />
</div>
);
}Xato:
TS2322: Type '{ name: string; pirce: number; }' is not assignable to type 'IntrinsicAttributes & MenuCardProps'.
Property 'pirce' does not exist on type 'IntrinsicAttributes & MenuCardProps'. Did you mean 'price'?
TS2741: Property 'price' is missing in type '{ name: string; }' but required in type 'MenuCardProps'.
TS2322: Type 'string' is not assignable to type 'number'.Har birini tarjima qilamiz:
- "
{ name; pirce }turiniIntrinsicAttributes & MenuCardPropsga berib bo'lmaydi.pircedegan xususiyat yo'q.priceni nazarda tutdingizmi?" — tsc hatto to'g'ri nomni taklif qildi. - "
{ name }turidapriceyo'q, lekinMenuCardPropsda u majburiy." — yetishmagan prop. - "
stringninumberga berib bo'lmaydi." —price="28000"qo'shtirnoqda, ya'ni satr. Son kerak bo'lsa —price={28000}.
Birinchi xabardagi IntrinsicAttributes nima? Bu — React har komponentga o'zi qo'shadigan atributlar, asosan key. Shuning uchun <MenuCard key="1" … /> ham xatosiz: key props turida yo'q, lekin IntrinsicAttributes da bor. & — kesishma: "ikkalasining hamma xususiyati".
Tekshirib ko'ring: Uchinchi xabar nega
MenuCardPropsni emas, faqatstringvanumberni tilga oldi?
Javob
Chunki obyektning shakli to'g'ri: name ham, price ham bor. Muammo bitta xususiyatning qiymatida. tsc xatoni eng aniq joyga — price="28000" ga qo'yadi va faqat shu qiymat turini aytadi. Qator va ustun raqami (index.tsx(10,32)) ham aynan price ni ko'rsatadi.
2.4 type yoki interface?
Props'ni interface bilan ham yozish mumkin, ikkalasi deyarli bir xil ishlaydi:
interface DishProps {
name: string;
price: number;
}
function Dish({ name, price }: DishProps) {
return <li>{name}: {price}</li>;
}
export default function App() {
return (
<ul>
<Dish name="Ko'k choy" price={5000} />
</ul>
);
}Ekranda:
Ko'k choy: 5000Farq props uchun kam uchraydi. Asosiysi: type union bo'la oladi (A | B), interface esa yo'q. 37-darsda props'ni aynan union qilamiz (React + TS IV). interface ning o'z kuchi — declaration merging, unga 38-darsda yetamiz (Kutubxona turlari). Loyiha ichida bittasini tanlab, izchil bo'lish muhim. vazifalar da props — type.
3. Ixtiyoriy props va standart qiymat
3.1 ? va standart qiymat
Ba'zi props'ni berish shart emas. Masalan, taom yonidagi yorliq: ko'pincha "yangi", lekin boshqa matn ham bo'lishi mumkin. Ixtiyoriy xususiyat — ? bilan, standart qiymat esa destrukturizatsiyada:
type BadgeProps = {
label: string;
tone?: "yashil" | "qizil";
};
function Badge({ label, tone = "yashil" }: BadgeProps) {
return (
<p>
[{tone}] {label}
</p>
);
}
export default function App() {
return (
<div>
<Badge label="Yangi" />
<Badge label="Tugadi" tone="qizil" />
</div>
);
}Ekranda:
[yashil] Yangi
[qizil] TugadiKomponent ichida tone turi — "yashil" | "qizil", undefined emas. Standart qiymat bo'shliqni yopdi va TypeScript buni tushunadi. Funksiya komponentlarida standart qiymatning yagona to'g'ri joyi — shu. Eski kodda Badge.defaultProps = { … } ni ko'rasiz. React 19 uni funksiya komponentlarida olib tashlagan, u class komponentlarda qoldi (Class komponentlar).
3.2 exactOptionalPropertyTypes tuzog'i
vazifalar ning tsconfig.app.json ida bitta qat'iy bayroq bor: exactOptionalPropertyTypes (Strict bayroqlar oilasi). U tone?: … ni "berilmasligi mumkin" deb o'qiydi, lekin "undefined berilishi mumkin" deb emas. Farqi ota komponentda chiqadi:
// @ts-options: {"exactOptionalPropertyTypes": true}
type BadgeProps = { label: string; tone?: "yashil" | "qizil" };
function Badge({ label, tone = "yashil" }: BadgeProps) {
return <p>[{tone}] {label}</p>;
}
function DishBadge({ soldOut }: { soldOut: boolean }) {
const tone = soldOut ? "qizil" : undefined;
return <Badge label="Osh" tone={tone} />;
}
export default DishBadge;Xato:
TS2375: Type '{ label: string; tone: "qizil" | undefined; }' is not assignable to type 'BadgeProps' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties."Bu tur exactOptionalPropertyTypes: true bilan BadgeProps ga mos emas. Nishon xususiyatlari turiga undefined qo'shishni o'ylab ko'ring." Ikki yo'l bor:
- Komponent tomonda:
tone?: "yashil" | "qizil" | undefined. Endiundefinedni ochiq uzatish ham mumkin. Qayta ishlatiladigan komponentlar uchun shu qulay — ota tomonda shart yozish shart emas.vazifalardagiTugmada aynan shunday:ref?: Ref<HTMLButtonElement> | undefined. - Ota tomonda: prop'ni umuman bermaslik —
{...(soldOut ? { tone: "qizil" } : {})}. Bu noqulay, shuning uchun birinchisi ko'proq uchraydi.
Nega bu bayroq kerak? U "xususiyat yo'q" va "xususiyat bor, qiymati undefined" ni ajratadi. "tone" in props va Object.keys uchun bu ikki holat farq qiladi (Obyekt metodlari). Bayroq farqni ko'rinadigan qiladi.
3.3 readonly props
Props — faqat o'qish uchun: komponent ularni o'zgartirmaydi. TypeScript buni readonly bilan majburlay oladi:
type PriceProps = { readonly price: number };
function Price(props: PriceProps) {
props.price = 0;
return <p>{props.price}</p>;
}
export default function App() {
return <Price price={35000} />;
}Xato:
TS2540: Cannot assign to 'price' because it is a read-only property."price ga yozib bo'lmaydi — u faqat o'qiladigan xususiyat". Amalda ko'p jamoalar har prop'ga readonly yozmaydi: destrukturizatsiya qilingan price baribir mahalliy o'zgaruvchi, uni o'zgartirish props'ga tegmaydi. readonly ko'proq massiv props uchun foydali: items: readonly Dish[] — komponent ichida items.push(…) endi xato. vazifalar da shunday: boshlangichRoyxat: readonly VazifaMalumoti[].
4. children turlari
4.1 ReactNode — eng keng tur
children va kompozitsiya darsida children: ReactNode deb yozgan edik. Endi ichiga qaraymiz. ReactNode — JSX'da {} ichiga qo'yish mumkin bo'lgan hamma narsa. Diagrammada uning tarkibi (@types/react 19.3.0 ta'rifidan):
flowchart TD
N["ReactNode"] --> E["ReactElement: <p>, <MenuCard />"]
N --> S["string, number, bigint"]
N --> B["boolean, null, undefined: hech narsa chizilmaydi"]
N --> I["Iterable<ReactNode>: massiv"]
N --> P["ReactPortal: createPortal natijasi"]
N --> R["Promise: use() bilan, 18/04"]Pastki qatordagi ikkitasiga e'tibor bering. ReactPortal — Portallar darsidagi createPortal natijasi. Promise esa React 19 da qo'shildi: Suspense ichida Promise ham bola bo'la oladi (use()). Diagrammada yo'q narsa — oddiy obyekt va funksiya. Ular ReactNode emas, shuning uchun {order} va {getPrice} tsc xatosi beradi (JSX II).
Ko'p hollarda children: ReactNode — to'g'ri tanlov. Karta, panel, modal, layout — ichiga istalgan narsa tushadi.
4.2 children turida bo'lmasa
Props turida children bo'lmasa, komponent bola qabul qilmaydi:
function Title({ text }: { text: string }) {
return <h2>{text}</h2>;
}
export default function App() {
return <Title text="Bugungi menyu">35 000 so'm</Title>;
}Xato:
TS2322: Type '{ text: string; children: string; }' is not assignable to type 'IntrinsicAttributes & { text: string; }'.
Property 'children' does not exist on type 'IntrinsicAttributes & { text: string; }'."children xususiyati { text: string } turida yo'q." Bu foydali: JS'da "35 000 so'm" jim yo'qolib ketardi, chunki Title uni hech qayerga chiqarmaydi. TypeScript ochiq-oydin aytdi.
4.3 ReactElement — faqat element
Ba'zan bola faqat element bo'lishi kerak, matn emas. Masalan, Tooltip bolasiga aria-describedby qo'shmoqchi. Buning uchun bola element bo'lishi shart:
import type { ReactElement } from "react";
function Tooltip({ children }: { children: ReactElement }) {
return <span className="tooltip">{children}</span>;
}
export default function App() {
return <Tooltip>Osh</Tooltip>;
}Xato:
TS2747: 'Tooltip' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'ReactElement<unknown, string | JSXElementConstructor<any>>'."Tooltip komponenti matnni bola sifatida qabul qilmaydi. JSX'dagi matn — string, kutilgan tur esa ReactElement." <Tooltip><button>Osh</button></Tooltip> — xatosiz.
Bitta muhim cheklov. ReactElement faqat "bu element" deydi. "Bu <button>" yoki "bu <MenuCard />" deb talab qila olmaydi. JSX ifodasining turi doim umumiy JSX.Element — tsc qaysi komponentdan yasalganini eslab qolmaydi. Shuning uchun children: ReactElement<ButtonProps> yozsangiz ham, <Tooltip><div /></Tooltip> o'tib ketadi. Aniq turdagi bolani talab qilish kerak bo'lsa — boshqa yo'l: slot prop yoki compound komponent (Compound komponentlar).
4.4 JSX.Element va qaytish turi
Ba'zi kodda komponent qaytish turi ochiq yozilgan: function Icon(): JSX.Element. JSX.Element — bitta JSX ifodasi turi. Unda null yo'q:
import type { JSX } from "react";
function Discount({ percent }: { percent: number }): JSX.Element {
if (percent === 0) return null;
return <b>-{percent}%</b>;
}
export default function App() {
return <Discount percent={10} />;
}Xato:
TS2322: Type 'null' is not assignable to type 'Element'.Komponent null ham, satr ham qaytara oladi. Shuning uchun qaytish turini yozmoqchi bo'lsangiz — ReactNode. Yaxshisi esa — umuman yozmaslik: TypeScript uni o'zi chiqaradi. React ham komponent ReactNode qaytarishini kutadi.
| Tur | Nima kiradi | Qachon |
|---|---|---|
ReactNode |
hammasi: matn, son, element, null, massiv |
children, slot prop'lar |
ReactElement |
faqat element | bolani klonlash yoki o'rash kerak bo'lsa |
JSX.Element |
bitta JSX ifodasi | eski kodda qaytish turi |
string |
faqat matn | title, label kabi oddiy matnlar |
4.5 PropsWithChildren
@types/react da kichik yordamchi tur bor: PropsWithChildren<P>. U P ga children?: ReactNode qo'shadi:
import type { PropsWithChildren } from "react";
type PanelProps = PropsWithChildren<{ title: string }>;
function Panel({ title, children }: PanelProps) {
return (
<section>
<h2>{title}</h2>
{children}
</section>
);
}
export default function App() {
return (
<Panel title="Ichimliklar">
<p>Ko'k choy — 5000 so'm</p>
</Panel>
);
}Ekranda:
Ichimliklar
Ko'k choy — 5000 so'mQulay, lekin bir nozik joyi bor: children bu yerda ixtiyoriy. <Panel title="Bo'sh" /> ham xatosiz o'tadi. Bo'sh panel ma'nosiz bo'lsa — children: ReactNode ni o'zingiz, ? siz yozing. Ko'p jamoalar shu sababli PropsWithChildren dan ko'ra ochiq children: ReactNode ni afzal ko'radi: tur nima talab qilishi bir qarashda ko'rinadi.
Tekshirib ko'ring:
type CardProps = { children: ReactNode }bo'lsa,<Card />(bolasiz) xato beradimi?<Card>{null}</Card>-chi?
Javob
<Card /> — xato (TS2741: Property 'children' is missing…): xususiyat majburiy, lekin umuman berilmagan. <Card>{null}</Card> esa xatosiz: children berildi, qiymati null, null esa ReactNode ga kiradi. Demak children: ReactNode "bo'sh bo'lmasin" degani emas, faqat "yozilishi shart" degani. Haqiqatan bo'sh emasligini tekshirish — ish vaqtidagi mantiq.
5. React.FC munozarasi
5.1 Ikki yozuv
Internetdagi ko'p misolda komponent boshqacha yozilgan:
import type { FC } from "react";
type PriceTagProps = { price: number };
const PriceTag: FC<PriceTagProps> = ({ price }) => {
return <p>{price} so'm</p>;
};
export default function App() {
return <PriceTag price={28000} />;
}Ekranda:
28000 so'mFC — "function component" turi (to'liq nomi FunctionComponent). U o'zgaruvchiga tur beradi: "bu — props'i PriceTagProps bo'lgan komponent". Ishlaydi. Unda nega kurs va vazifalar uni ishlatmaydi?
5.2 Tarix: yashirin children
2022-yilgacha (@types/react 18 dan oldin) FC har komponentga yashirin children qo'shardi. <PriceTag price={1}>matn</PriceTag> xatosiz o'tardi, matn esa jim yo'qolardi — «children turida bo'lmasa» bo'limidagi himoya ishlamasdi. Shuning uchun ko'p jamoa FC dan voz kechdi. Hozir children olib tashlangan va FC ham bolasiz komponentni to'g'ri tekshiradi:
import type { FC } from "react";
const Card: FC<{ title: string }> = ({ title, children }) => (
<section>
<h2>{title}</h2>
{children}
</section>
);
export default function App() {
return <Card title="Osh" />;
}Xato:
TS2339: Property 'children' does not exist on type '{ title: string; }'.Eski darslikdagi FC kodini ko'chirsangiz, aynan shu xatoni olasiz. Davosi — children ni props turiga o'zingiz yozish.
5.3 Bugungi tanlov
function X(props: XProps) |
const X: FC<XProps> |
|
|---|---|---|
children |
turda yozilsa bor | turda yozilsa bor (18 dan) |
| generic komponent | function List<T>(…) |
FC ni generic qilib bo'lmaydi |
| hoisting | e'londan oldin ishlatsa bo'ladi | const — oldin emas |
displayName turi |
yo'q (kerak emas) | bor |
Asosiy farq — ikkinchi qator. Generic komponent (<List<Dish> items={…} />) React + TS IV darsida kerak bo'ladi va FC bilan yozib bo'lmaydi. Shuning uchun bu kursda — oddiy funksiya va turlangan props. FC ni begona kodda ko'rsangiz — xato emas, shunchaki boshqa uslub. Uni "to'g'rilash" uchun kodni qayta yozish shart emas.
6. Props turini qayta ishlatish
Ba'zan boshqa komponentning props turi kerak bo'ladi. Masalan, MenuCard ni o'raydigan FeaturedCard yozyapsiz. Tur eksport qilinmagan bo'lsa ham, ComponentProps bilan uni komponentdan "sug'urib olish" mumkin:
import type { ComponentProps } from "react";
function MenuCard({ name, price }: { name: string; price: number }) {
return <p>{name} — {price} so'm</p>;
}
type MenuCardProps = ComponentProps<typeof MenuCard>;
function FeaturedCard(props: MenuCardProps) {
return (
<div>
<b>Kun taomi:</b>
<MenuCard {...props} />
</div>
);
}
export default function App() {
return <FeaturedCard name="Lag'mon" price={28000} />;
}Ekranda:
Kun taomi:
Lag'mon — 28000 so'mtypeof MenuCard — funksiyaning turi (typeof turlarda). ComponentProps undan birinchi argument turini chiqaradi. Ichida infer bor: T extends JSXElementConstructor<infer Props> ? Props : …. Xuddi shu yordamchi HTML teglari uchun ham ishlaydi: ComponentProps<"button"> — <button> ning hamma atributlari. Bu — keyingi darsdan keyingi mavzu (React + TS III).
7. Vazifalar qadami: TS qadami boshlanadi
7.1 Besh dars — bitta branch
34–38-darslar vazifalar da bitta qadam: refactor/turlar branch'i. Har dars o'z bo'lagini qo'shadi, commit — 38-darsda. Bugungi bo'lak — tur tekshiruvini qat'iyroq qilish:
git switch -c refactor/turlarAvval mavjud props'ga qarang. App ning props turi:
type Props = {
boshlangichRoyxat: readonly VazifaMalumoti[]; // localStorage'dan
qoralama: string; // forma ochilgandagi matn
};Bugungi darsning hamma qoidasi bor: type, nom — Props (fayl ichida bitta komponent), massiv — readonly, children yo'q (App bola qabul qilmaydi), React.FC yo'q.
7.2 Uch yangi bayroq — o'lchab qo'shildi
tsconfig.app.json da strict dan tashqari yana yettita bayroq bor edi (15/#34 va 16/#42). Kanon yana uchtasini sinab ko'rdi. Har bayroq yoqilib, tsc -b ishga tushirildi va xatolar sanaldi (natijalar/38-turlar.txt). Bayroqlar nima qilishini avval kichik faylda ko'ramiz:
// @ts-options: {"allowUnreachableCode": false}
import "./tema-yoq.ts";
function price(): number {
return 35000;
console.log("hech qachon");
}
console.log(price());Xato:
TS2882: Cannot find module or type declarations for side-effect import of './tema-yoq.ts'.
TS7027: Unreachable code detected.TS2882— "yon ta'sirli import (import "./fayl", nomsiz) fayli topilmadi". BunoUncheckedSideEffectImports. Nomli importni tsc doim tekshiradi, nomsizini esa ilgari o'tkazib yuborardi. Fayl nomida xato bo'lsa — build'da jim yo'qolardi.TS7027— "yetib bo'lmaydigan kod". Bayroqsiz bu faqat muharrirdagi xira ko'rinish,allowUnreachableCode: falseesa uni xatoga aylantiradi.- Uchinchi bayroq —
allowUnusedLabels: false. Hech qayerdabreak tashqibilan ishlatilmagantashqi:label'i —TS7028: Unused label.xatosi.
To'rtinchi bayroq boshqacha — u xato emas, yozish uslubini tekshiradi:
// @ts-options: {"noPropertyAccessFromIndexSignature": true}
const li = document.createElement("li");
li.dataset.id = "7";
console.log(li.dataset.id, li.dataset["id"]);Xato:
TS4111: Property 'id' comes from an index signature, so it must be accessed with ['id'].
TS4111: Property 'id' comes from an index signature, so it must be accessed with ['id']."id index signature'dan keladi (Index signature), uni ['id'] bilan o'qing." dataset — har qanday nomni qabul qiladigan obyekt. Bayroq "bunday nom bor-yo'qligi noma'lum, buni ko'rinib tursin" deydi. Qavsli li.dataset["id"] — xatosiz.
Bitta kuzatuv. Biz noUncheckedSideEffectImports ni yoqmadik, lekin TS2882 baribir chiqdi. tsc 7.0.2 da bu tekshiruv standart holatda yoqilgan. Kanon uni baribir aniq yozdi: sozlama faylni o'qigan odam qaror ko'rinib tursin.
Endi vazifalar dagi haqiqiy natija:
| Bayroq | vazifalar da xato |
Qaror |
|---|---|---|
noUncheckedSideEffectImports |
0 | kirdi |
allowUnreachableCode: false |
0 | kirdi |
allowUnusedLabels: false |
0 | kirdi |
noPropertyAccessFromIndexSignature |
20 (hammasi TS4111) |
kirmadi |
Uchtasi — "bepul himoya": bugun 0 xato, ertangi xatoni ushlaydi. To'rtinchisi 20 joyda dataset.id ni dataset["id"] ga o'zgartirishni talab qildi. Bu xato topmaydi, faqat yozish uslubini o'zgartiradi. Shuning uchun kirmadi, sababi izohda yozildi:
// 18/#34: yana uchta — o'lchandi, kanonda 0 xato (bepul himoya):
// yon ta'sirli import fayli yo'q bo'lsa xato, yetib bo'lmaydigan kod
// va ishlatilmagan label — xato (ogohlantirish emas).
// noPropertyAccessFromIndexSignature (20 joy — dataset.id ni
// dataset["id"] qilish) va typescript-eslint strictTypeChecked (70,
// hammasi uslub) — o'lchandi, kiritilmadi (natijalar/38-*)
"noUncheckedSideEffectImports": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,7.3 strictTypeChecked — 70 topilma, 0 xato
Izohdagi ikkinchi o'lchov — ESLint tomonda. vazifalar da typescript-eslint'ning recommendedTypeChecked to'plami ishlaydi (ESLint II). Undan qat'iyroq — strictTypeChecked. U vaqtincha yoqildi va src/ da 70 topilma berdi:
- no-confusing-void-expression40 ta
- restrict-template-expressions24 ta
- no-unnecessary-condition4 ta
- no-meaningless-void-operator2 ta
Manba: vazifalar v8, natijalar/38-turlar.txt — typescript-eslint 8.71.1, 2026-10-13
Grafikdagi eng uzun ikki ustun — uslub. no-confusing-void-expression () => setOchiq(false) kabi qisqa strelkalarni yoqtirmaydi. restrict-template-expressions esa shablon satrga son qo'yishni (`${narx} so'm`) taqiqlaydi. no-unnecessary-condition ning 4 tasi ko'rib chiqildi: biri ataylab yozilgan never tekshiruvi (37-darsda), qolganlari lib.dom turlari bilan bog'liq. Real xato — 0. Qaror: kirmadi. Bu "o'lchab qaror qilish" — xuddi React Compiler darsidagidek: qoida qanchalik qat'iy bo'lmasin, foydasini raqam bilan ko'rsatmasa, kodga yuk bo'ladi.
Tekshirib ko'ring: Nega
noPropertyAccessFromIndexSignature"kirmadi",allowUnreachableCode: falseesa "kirdi" — ikkalasi ham xato ushlaydigan bayroq emasmi?
Javob
Mezon — narx va foyda. Bayroq allowUnreachableCode: false bugun 0 o'zgarish talab qildi, ertaga esa haqiqiy xatoni (masalan, return dan keyin qolgan kod) ushlaydi. Bayroq noPropertyAccessFromIndexSignature esa 20 joyni o'zgartirishni talab qildi va ularning birortasi ham xato emas edi: dataset.id va dataset["id"] bir xil ishlaydi. Narx bor, foyda ko'rinmadi.
Tekshiruvlar (shu bo'lakdan keyin, kanon): npm run tip — 0 xato, npm run lint va npm test — o'zgarishsiz toza. Commit hali yo'q.
8. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
TS1161: Unterminated regular expression literal |
JSX .ts faylda |
fayl kengaytmasi — .tsx |
TS2322 … Did you mean 'price'? |
prop nomida xato | tsc taklif qilgan nom |
TS2741: Property 'x' is missing |
majburiy prop berilmagan | prop'ni bering yoki turda x? |
TS2375 … exactOptionalPropertyTypes |
ixtiyoriy prop'ga undefined uzatildi |
turga | undefined qo'shing |
TS2322 … 'children' does not exist |
turda children yo'q |
children: ReactNode qo'shing |
TS2339: Property 'children' does not exist |
eski FC kodi |
children ni turga yozing |
TS2322: Type 'null' is not assignable to type 'Element' |
qaytish turi JSX.Element |
ReactNode yoki tursiz |
9. Mashqlar
Mashqlar kurs/mashqlar/18/34-props-turlari/ da. Har yechimni «Ishga tushir» bilan sinang, tip xatolarini esa «TS Playground'da ochish» yoki o'z loyihangizda npm run tip bilan.
1-mashq (oson): qaysi tur?
Har holatga mos turni yozing: ReactNode, ReactElement yoki string.
- Kartaning sarlavhasi — faqat matn,
<h2>ga qo'yiladi. - Modal oynaning ichi — matn, forma, rasm, hammasi bo'lishi mumkin.
Tooltipbolasi — ungaaria-describedbyqo'shib klonlanadi.
Yechim
- string — sarlavha faqat matn bo'lsa, eng tor tur eng aniq.
<b>kerak bo'lib qolsa —ReactNodega kengaytirasiz. - ReactNode — modal ichiga istalgan narsa tushadi, bu
childrenning odatiy turi. - ReactElement — klonlash uchun element kerak, matn emas (
TS2747himoyasi). Lekin aniq qaysi element ekanini bu tur kafolatlamaydi.
2-mashq (o'rta): kartaga tur yozing
OrderLine komponentiga props turi yozing: dish (satr, majburiy), count (son, ixtiyoriy, standart 1), note (ixtiyoriy, istalgan ReactNode). note bo'lsa — qator ostida <small> da chiqsin. Ishora: standart qiymat — destrukturizatsiyada («? va standart qiymat» bo'limi), note uchun && (Shartli render).
export default function App() {
return (
<ul>
<OrderLine dish="Osh" count={2} />
<OrderLine dish="Ko'k choy" note={<i>shakarsiz</i>} />
</ul>
);
}Yechim
import type { ReactNode } from "react";
type OrderLineProps = {
dish: string;
count?: number;
note?: ReactNode;
};
function OrderLine({ dish, count = 1, note }: OrderLineProps) {
return (
<li>
{dish} × {count}
{note && <small> ({note})</small>}
</li>
);
}
export default function App() {
return (
<ul>
<OrderLine dish="Osh" count={2} />
<OrderLine dish="Ko'k choy" note={<i>shakarsiz</i>} />
</ul>
);
}Ekranda:
Osh × 2
Ko'k choy × 1 (shakarsiz)Komponent ichida count turi — number: standart qiymat undefined ni yopdi. Prop note esa ReactNode, shuning uchun unga element ham (<i>), matn ham berish mumkin. Bitta nozik joy: note ga son berilsa, 0 && tuzog'i (JSX II) qaytadi. Qat'iy bo'lish uchun note !== undefined && yozing.
3-mashq (qiyin): FC kodni ko'chirish
Eski loyihadan ko'chirilgan kod tsc'dan o'tmayapti:
import type { FC } from "react";
type SectionProps = { title: string; empty?: boolean };
const Section: FC<SectionProps> = ({ title, empty, children }) => (
<section>
<h2>{title}</h2>
{empty ? <p>Hozircha bo'sh</p> : children}
</section>
);
export default function App() {
return (
<Section title="Shirinliklar">
<p>Chak-chak</p>
</Section>
);
}Xato:
TS2339: Property 'children' does not exist on type 'SectionProps'.
TS2322: Type '{ title: string; children: Element; }' is not assignable to type 'IntrinsicAttributes & SectionProps'.
Property 'children' does not exist on type 'IntrinsicAttributes & SectionProps'.Kodni bugungi uslubga o'tkazing: FC siz, oddiy function, children turda ochiq va majburiy. Nega eski kod qachonlardir ishlagan edi — bir gap bilan tushuntiring.
Yechim
import type { ReactNode } from "react";
type SectionProps = {
title: string;
empty?: boolean;
children: ReactNode;
};
function Section({ title, empty = false, children }: SectionProps) {
return (
<section>
<h2>{title}</h2>
{empty ? <p>Hozircha bo'sh</p> : children}
</section>
);
}
export default function App() {
return (
<Section title="Shirinliklar">
<p>Chak-chak</p>
</Section>
);
}Ekranda:
Shirinliklar
Chak-chakEski kod @types/react 17 va undan oldin ishlagan. O'shanda FC har komponentga yashirin children?: ReactNode qo'shardi. Versiya 18 da bu olib tashlandi, shuning uchun ikki xato chiqdi. Biri komponent ichida (children ni o'qish), biri ishlatilgan joyda (children berish). Yechimdagi empty = false — ixtiyoriy boolean uchun aniq standart. Bu shart emas (undefined ham "yolg'on"), lekin o'qishni osonlashtiradi.
4-mashq: Vazifalar qadami
refactor/turlar branch'ini oching. tsconfig.app.json ga uchta bayroqni izohi bilan qo'shing (Vazifalar qadami bo'limidagi parcha). Keyin o'lchang: avval noPropertyAccessFromIndexSignature ni ham vaqtincha qo'shib, npm run tip dagi TS4111 larni sanang, so'ng uni olib tashlang.
Yechim
Tekshiruv ro'yxati:
- Uch bayroq bilan
npm run tip— 0 xato. - Vaqtincha
noPropertyAccessFromIndexSignaturebilan —TS4111lar (kanonda 20 ta:App.tsxdagidataset.id,dataset.amal,paket.tsdagiRecord<string, unknown>o'qishlari). Sizda raqam boshqacha bo'lishi mumkin, agar kodingiz kanondan farq qilsa. - Bayroq olib tashlandi, izohda — nega kirmagani.
npm run lint,npm test— toza. - Commit hali yo'q — 38-darsda, beshta bo'lak bilan birga.
10. Real ishda
- Kod ko'rigi (code review) da birinchi qaraladigan joylardan biri — komponentning props turi. U komponentning "shartnomasi": nima majburiy, nima ixtiyoriy,
childrenqanday. - Dizayn tizimlari (MUI, Mantine, Radix) props turlarini eksport qiladi:
ButtonProps. Eksport qilinmagan bo'lsa —ComponentProps<typeof Button>. React.FCmunozarasi intervyuda tez-tez so'raladi: "FC ishlatasizmi, nega?". Javob: "props'ni to'g'ridan-to'g'ri turlayman — generic bilan ishlaydi,childrenturda ochiq".- tsconfig bayroqlari — yangi loyihada
create-viteshablonidan boshlanadi, keyin jamoa o'lchab qo'shadi. "Hamma bayroqni yoqish" ham, "hech birini" ham — yomon qaror.
Xulosa
- Props turi — oddiy obyekt turi:
type XProps = { … }, komponentda({ a, b }: XProps). - Ixtiyoriy —
?, standart qiymat — destrukturizatsiyada.exactOptionalPropertyTypesdaundefineduzatish uchun —| undefined. children: odatdaReactNode, faqat element —ReactElement, faqat matn —string. Turda bo'lmasa — bola qabul qilinmaydi.React.FCishlaydi, lekin generic bo'lmaydi; zamonaviy uslub — turlangan props bilan oddiy funksiya.vazifalar:refactor/turlarboshlandi — uch tsc bayrog'i kirdi (0 xato),noPropertyAccessFromIndexSignature(20) vastrictTypeChecked(70, real xato 0) — kirmadi.
Keyingi dars: React + TS II: hooklar turlari — useState, useRef, useReducer va Context'ga tur berish va null tuzog'i.
Manbalar
- React: "Using TypeScript" — react.dev/learn/typescript (2026-10 holatiga, React 19.3)
- TypeScript:
exactOptionalPropertyTypes— typescriptlang.org/tsconfig#exactOptionalPropertyTypes - TypeScript:
noUncheckedSideEffectImports— typescriptlang.org/tsconfig#noUncheckedSideEffectImports @types/react19.3.0 —ReactNode,PropsWithChildren,FunctionComponentta'riflari (index.d.ts)- typescript-eslint: Shared Configs (
strict-type-checked) — typescript-eslint.io/users/configs
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!