Mundarija (31)
- Bu darsda
- 1. Nega bu kerak?
- 2. Turlar qayerdan keladi
- 2.1 Uch manba
- 2.2 @types versiyasi
- 2.3 TS7016: turi yo'q paket
- 3. Declaration merging
- 3.1 Bir nomli ikki interfeys
- 3.2 Global turlarni kengaytirish
- 4. declare module: kutubxona turini kengaytirish
- 4.1 React'ning CSSProperties i
- 4.2 Augmentation butun loyihaga ta'sir qiladi
- 4.3 Qayerga yozish
- 5. vite-env.d.ts va env turlari
- 6. "Register" naqshi
- 6.1 Muammo: kutubxona sizning ma'lumotingizni bilmaydi
- 6.2 O'z kichik kutubxonamiz
- 6.3 Haqiqiy kutubxonalarda
- 7. Vazifalar qadami: react-kengaytma.d.ts va commit
- 7.1 Teg ulushi chizig'i
- 7.2 Tuzoq: test loyihasi .d.ts ni ko'rmadi
- 7.3 Commit
- 8. Ko'p uchraydigan xatolar
- 9. Mashqlar
- 1-mashq (oson): tur qayerdan?
- 2-mashq (o'rta): data-* emas, CSS o'zgaruvchisi
- 3-mashq (qiyin): o'z "register" ingiz
- 4-mashq: Vazifalar qadami
- 10. Real ishda
- Xulosa
- Manbalar
Kutubxona turlari va module augmentation: @types, declare module va "register" naqshi
Qisqacha: Kutubxona turlari uch joydan keladi: paketning o'zidan (
"types"maydoni), DefinitelyTyped'dagi@types/…paketidan yoki loyihangizdagi.d.tsfaylidan. Tur yetarli bo'lmasa, uni kutubxona kodiga tegmasdan kengaytirish mumkin. Bu — module augmentation:declare module "react" { interface CSSProperties { … } }. U interfeyslarning bir-biriga qo'shilishiga (declaration merging) tayanadi. Zamonaviy kutubxonalar (TanStack Router, i18next) shu yo'l bilan "register" qilinadi. Siz o'z router'ingiz yoki tarjima kalitlaringizni bir marta e'lon qilasiz, butun loyiha ularni biladi.
Bu darsda
- Tur qayerdan kelishini (paket,
@types,.d.ts) aniqlaysiz vaTS7016xatosini tuzatasiz. - Declaration merging va
declare modulebilan kutubxona turini kengaytirasiz. vite-env.d.tsvaImportMetaEnvqanday ishlashini tushuntira olasiz.- "Register" naqshini o'zingiz yasab ko'rasiz — i18next va TanStack Router uni qanday ishlatishini tushunasiz.
vazifalardastyledagi CSS o'zgaruvchilari uchun React turini kengaytirasiz va TS qadamini commit qilasiz.
Oldin bilishingiz kerak: React + TS IV, Declaration fayllari, Kengaytirish va declaration merging, tsconfig Vite + React loyihada.
1. Nega bu kerak?
vazifalar dagi batafsil statistikada har teg yonida "bajarilgan ulush" chizig'i kerak bo'ldi: 2 tadan 1 tasi bajarilgan — chiziqning yarmi yashil. Chiziq uzunligi har qatorda boshqa, demak qiymat JS'dan keladi. Eng toza yo'l — CSS o'zgaruvchisi (Custom properties):
<span className="ulush" style={{ "--ulush": "50%" }} />Brauzerda bu ishlaydi. tsc esa rozi emas:
TS2353: Object literal may only specify known properties, and '"--ulush"' does not exist in type 'Properties<string | number, string & {}>'."Obyekt literalida faqat ma'lum xususiyatlar bo'lishi mumkin, --ulush esa Properties turida yo'q." React'ning style turi faqat color, width kabi standart CSS xususiyatlarini biladi. CSS o'zgaruvchilari — -- bilan boshlanadigan istalgan nom, ularni oldindan sanab bo'lmaydi.
Nima qilamiz? as any — tekshiruvni o'chiradi. @types/react faylini node_modules da tahrirlash — keyingi npm install da o'chib ketadi.
Hayotiy o'xshatish: oshxonaga kelgan tayyor menyu kitobi. Uni chop etgan bosmaxonaga borib qayta chop ettira olmaysiz. Lekin kitobning oxiriga qo'shimcha varaq yopishtira olasiz: "Bahor maxsus taomlari". Kitob o'sha, ro'yxat kengaydi. Module augmentation — aynan shu qo'shimcha varaq.
2. Turlar qayerdan keladi
2.1 Uch manba
import { useState } from "react" yozganingizda tsc useState turini qidiradi. Qidiruv tartibi diagrammada:
flowchart TD
I["import … from 'react'"] --> P{"paketda types bormi?"}
P -- "ha" --> T["paket.json: types → index.d.ts"]
P -- "yo'q" --> D{"@types/react bormi?"}
D -- "ha" --> DT["DefinitelyTyped turlari"]
D -- "yo'q" --> L{"loyihada declare module bormi?"}
L -- "ha" --> M["o'z .d.ts faylingiz"]
L -- "yo'q" --> E["TS7016: tur topilmadi"]- Paketning o'zida. Ko'p zamonaviy paketlar TypeScript'da yozilgan va turlarini o'zi olib keladi:
package.jsonda"types"(yoki"exports"ichida"types") maydoni (kirish nuqtalari). Zod, Vite, TanStack Query — shunday. @types/…paketi. React o'zi JavaScript'da yozilgan va tur olib kelmaydi. Uning turlari — alohida, jamoa yuritadigan DefinitelyTyped omboridagi@types/reactpaketida.vazifalardagidevDependencies:"@types/react": "19.3.0","@types/react-dom": "19.3.0".- Loyihangizdagi
.d.ts. Hech qayerda tur yo'q bo'lsa — o'zingiz yozasiz.
2.2 @types versiyasi
@types/react versiyasi react versiyasiga mos bo'lishi kerak: kamida asosiy va kichik raqam (19.3). Nega? Turlar — API tavsifi. <Activity> React 19.2 da barqaror eksportga aylandi (Activity). @types/react 19.0 bo'lsa, import { Activity } from "react" — tur xatosi, garchi kod ishlasa ham. Teskarisi ham bor: turlarda bor, kutubxonada yo'q funksiya — ish vaqtida undefined.
@types — har doim devDependencies da (bog'liqlik turlari): turlar build'da o'chadi, brauzerga bormaydi. vazifalar da ham shunday.
2.3 TS7016: turi yo'q paket
Kichik, turlarsiz paketni o'rnatdingiz deylik — confetti-uz (o'ylab topilgan nom; main: index.js, types yo'q, @types ham yo'q):
import confetti from "confetti-uz";
confetti();tsc 7.0.2 ning haqiqiy xabari (yo'l qisqartirildi):
TS7016: Could not find a declaration file for module 'confetti-uz'. '…/node_modules/confetti-uz/index.js' implicitly has an 'any' type.
Try `npm i --save-dev @types/confetti-uz` if it exists or add a new declaration (.d.ts) file containing `declare module 'confetti-uz';`"confetti-uz uchun e'lon fayli topilmadi, u yashirincha any." Xabarning o'zi ikki yo'l taklif qiladi:
@types/confetti-uzbormi — tekshiring (npmjs.com da qidiring).- Bo'lmasa — o'z
.d.tsfaylingiz. Eng qisqasideclare module "confetti-uz";— butun paketany. Yaxshisi — ishlatadigan qismingizni tavsiflash:
// src/turlar/confetti-uz.d.ts
declare module "confetti-uz" {
export default function confetti(sozlama?: { soni?: number }): void;
}Endi confetti({ soni: 50 }) — to'g'ri, confetti({ son: 50 }) — xato. Bu shablon bilan tsc xatosiz o'tishini tekshirdik. .d.ts — faqat tur, unda kod yo'q (Declaration fayllari).
Tekshirib ko'ring:
@types/reactnidependenciesga (devDependenciesemas) qo'ysangiz, foydalanuvchi brauzeriga nima ortiqcha yuklanadi?
Javob
Hech narsa. Bundler faqat import qilingan kodni to'playdi, .d.ts fayllarda esa kod yo'q. Farq boshqa joyda: npm install --omit=dev (masalan, server yoki Docker'da) @types ni ham o'rnatadi — ortiqcha megabaytlar, xavfsizlik ko'rigida ortiqcha paket. Qoida bo'yicha turlar — devDependencies.
3. Declaration merging
3.1 Bir nomli ikki interfeys
Augmentation'ning poydevori — TypeScript'ning bitta xususiyati. Bir xil nomli ikki interface — bitta interfeysga qo'shiladi (Kengaytirish va declaration merging):
interface Dish {
name: string;
}
interface Dish {
price: number;
}
const osh: Dish = { name: "Osh", price: 35000 };
console.log(osh); // { name: 'Osh', price: 35000 }Dish endi ikkala xususiyatni ham talab qiladi. type bilan bunday qilib bo'lmaydi — Duplicate identifier 'Dish'. Shuning uchun kutubxonalar kengaytirilishi kerak bo'lgan turlarni interface qilib yozadi. React ham: interface CSSProperties, interface HTMLAttributes.
3.2 Global turlarni kengaytirish
Brauzerning global turlari (Window, Document) ham interfeys. Ularga ham "varaq qo'shish" mumkin:
declare global {
interface Window {
bahorVersiya: string;
}
}
console.log(window.bahorVersiya.toUpperCase());
console.log(window.bahorVersiyaa);
export {};Xato:
TS2551: Property 'bahorVersiyaa' does not exist on type 'Window & typeof globalThis'. Did you mean 'bahorVersiya'?Birinchi qator xatosiz — bahorVersiya endi Window da bor. Ikkinchisida harf adashgan — tsc to'g'ri nomni taklif qildi. declare global { … } — "modul ichidan global turni kengaytirish". Pastdagi export {}; faylni modul qiladi: declare global faqat modul faylda ishlaydi.
vazifalar da shunday fayl bor — src/trusted-types.d.ts. U yerda modul emas, skript .d.ts bo'lgani uchun declare global siz yozilgan (kanondan, qisqartirilgan):
// Declaration merging: lib.dom dagi interfeysga yangi overload
// qo'shiladi — register() siyosatdan o'tgan manzilni ham qabul qiladi
interface ServiceWorkerContainer {
register(
manzil: string | URL | TrustedScriptURL,
sozlama?: RegistrationOptions,
): Promise<ServiceWorkerRegistration>;
}Brauzer navigator.serviceWorker.register ga Trusted Types obyektini ham qabul qiladi, lekin TypeScript'ning lib.dom i buni bilmaydi. Kanon bitta qo'shimcha "overload" yozdi — Web Worker darsidagi Trusted Types siyosati shu tufayli tsc'dan o'tdi.
Diqqat: Global turni kengaytirish — haqiqiy qiymat yaratmaydi.
window.bahorVersiyaturda bor, lekin uni kimdir haqiqatan yozmasa, ish vaqtidaundefined. Augmentation — va'da: "bu narsa bor". Va'dani bajarish — sizning ishingiz.
4. declare module: kutubxona turini kengaytirish
4.1 React'ning CSSProperties i
Endi «Nega bu kerak?» bo'limidagi muammoga qaytamiz. @types/react da style turi — CSSProperties interfeysi. Unga yangi a'zo qo'shamiz — -- bilan boshlanadigan istalgan kalit. Buning uchun template literal tur kerak: `--${string}`:
import { useEffect, useRef } from "react";
declare module "react" {
interface CSSProperties {
[ozgaruvchi: `--${string}`]: string | number | undefined;
}
}
export default function App() {
const ref = useRef<HTMLSpanElement>(null);
useEffect(() => {
const qiymat = ref.current?.style.getPropertyValue("--ulush");
console.log("--ulush =", qiymat);
}, []);
return (
<p>
#bozor{" "}
<span ref={ref} className="ulush" style={{ "--ulush": "50%" }}>
1/2
</span>
</p>
);
}Konsolda:
--ulush = 50%Ekranda:
#bozor 1/2O'qib chiqamiz:
declare module "react" { … }— "react moduli turlariga qo'shimcha". Kod emas, faqat tur. Build'da yo'qoladi.interface CSSProperties—@types/reactdagi o'sha nom. Declaration merging uni asl interfeys bilan birlashtiradi.[ozgaruvchi: `--${string}`]— index signature (Index signature): "--bilan boshlanadigan har qanday kalit".--ulush,--rang— ruxsat.-ulushyokiulush— yo'q, ular uchun eski tekshiruv ishlaydi.- Konsoldagi
50%— React qiymatni elementga haqiqatan yozdi. CSS o'zgaruvchilarini Reactstyle.setPropertybilan beradi.
Muhim: modul faylda declare module "react" — kengaytirish. Agar fayl modul bo'lmasa (import/export yo'q), xuddi shu yozuv react ning butun turini almashtirib yuborardi — boshqa hech narsa qolmasdi. Shuning uchun augmentation faylida doim kamida bitta import bo'ladi.
4.2 Augmentation butun loyihaga ta'sir qiladi
Kengaytirish yozilgan faylda emas, loyihada amal qiladi: tsc hamma fayllarni bitta dastur sifatida ko'radi. react-kengaytma.d.ts ga bir marta yozdingiz — App.tsx, BatafsilStatistika.tsx va har qanday boshqa fayl "--…" ni biladi.
Teskarisi ham rost: kengaytirish loyiha tekshiruviga kirmasa, u yo'q. Augmentation'siz holat — o'sha xato:
// @ts-options: {"noUnusedLocals": false}
export default function App() {
return <span style={{ "--ulush": "50%" }}>1/2</span>;
}Xato:
TS2353: Object literal may only specify known properties, and '"--ulush"' does not exist in type 'Properties<string | number, string & {}>'.// @ts-options qatori bu yerda faqat texnik sabab bilan: shu darsning tekshiruvchisi tsx bloklarini bitta loyiha qilib tekshiradi. Usiz yuqoridagi declare module bu blokka ham ta'sir qilib, xatoni "yashirardi". Bu — aynan shu bo'limning gapi, jonli ko'rinishda. «Vazifalar qadami» bo'limida xuddi shu tuzoq kanonda ham chiqdi.
4.3 Qayerga yozish
Kengaytirish — alohida .d.ts faylda. Bitta qoida — bitta fayl, nomi nima kengayishini aytsin: src/react-kengaytma.d.ts, src/turlar/i18next.d.ts. Komponent ichida yozish (yuqoridagi demo kabi) ishlaydi, lekin keyin uni hech kim topolmaydi.
5. vite-env.d.ts va env turlari
Vite III: env o'zgaruvchilar darsida import.meta.env.VITE_API_URL ga tur bergan edik. Endi bu fayl qanday ishlashini to'liq tushunamiz. vazifalar dagi src/vite-env.d.ts (kanondan aynan):
// import.meta.env turlari (16/#28): vite/client — MODE, DEV, PROD,
// BASE_URL; o'zimizniki — pastda (.env.production, .env.development)
/// <reference types="vite/client" />
// interface — Vite'ning ImportMetaEnv'i bilan birlashishi uchun
// (declaration merging, 15/T-16; type bilan bo'lmaydi)
interface ImportMetaEnv {
readonly VITE_API_URL: string;
}Ikki qism:
/// <reference types="vite/client" />— "Vite'ning brauzer turlarini qo'sh":import.meta.env.MODE,import.meta.hot,import x from "./rasm.png"kabi importlar turi.interface ImportMetaEnv— Vite ichida ham shu nomli interfeys bor. Declaration merging ularni qo'shadi.readonly— env build paytida qotadi, kod uni o'zgartirmaydi.
Bu fayl modul emas (import yo'q) — shuning uchun declare global kerak emas, interfeys o'zi global. CSS kengaytmasi esa import "react" bilan modul — chunki u modul turini kengaytiradi, global turni emas.
Backend'da xuddi shu g'oya process.env uchun bor: declare global { namespace NodeJS { interface ProcessEnv { DATABASE_URL: string } } }. Uni Node.js qismida ishlatamiz (Muhit o'zgaruvchilari).
6. "Register" naqshi
6.1 Muammo: kutubxona sizning ma'lumotingizni bilmaydi
Tarjima kutubxonasi t("salom") funksiyasini beradi. Kutubxona yozilganda sizning kalitlaringiz ma'lum emas edi, shuning uchun t istalgan satrni qabul qiladi. t("salomm") — harf adashgan, tsc jim, ekranda esa xom kalit chiqadi.
Zamonaviy kutubxonalar buni shunday hal qiladi: kutubxona bo'sh interfeys e'lon qiladi, siz uni augmentation bilan to'ldirasiz. Kutubxona turlari shu interfeysdan o'qiydi. Naqshni o'zimiz yasab ko'ramiz — uch faylda.
6.2 O'z kichik kutubxonamiz
Birinchi fayl — "kutubxona". Register — bo'sh interfeys, Kalit esa undan tur chiqaradi (Conditional types, infer):
// fayl: tarjima.ts — kichik "kutubxona"
export interface Register {}
type Kalit = Register extends { kalitlar: infer K extends string }
? K
: string;
const lugat: Record<string, string> = {
salom: "Xush kelibsiz!",
menyu: "Bugungi menyu",
};
export function t(kalit: Kalit): string {
return lugat[kalit] ?? kalit;
}Register bo'sh — kalitlar yo'q, shuning uchun Kalit = string. Ilova hali ro'yxatdan o'tmagan:
// fayl: ilova.ts — kalitlar ro'yxatdan o'tmagan
import { t } from "./tarjima.ts";
console.log(t("salom"));
console.log(t("salomm"));Konsolda:
Xush kelibsiz!
salommtsc jim, ekranda xom salomm. Endi ikkinchi fayl — "register":
// fayl: kalitlar.d.ts — kutubxonani "register" qilish
import "./tarjima.ts";
declare module "./tarjima.ts" {
interface Register {
kalitlar: "salom" | "menyu";
}
}O'sha ilova.ts — o'zgarishsiz:
// fayl: ilova.ts — endi kalitlar tekshiriladi
import { t } from "./tarjima.ts";
console.log(t("salom"));
console.log(t("salomm"));Xato:
TS2345: Argument of type '"salomm"' is not assignable to parameter of type '"menyu" | "salom"'.Kutubxona kodi o'zgarmadi, ilova kodi ham. Faqat bitta .d.ts qo'shildi — va t ning parametri string dan "menyu" | "salom" ga torayib qoldi. Muharrir endi kalitlarni avtomatik taklif ham qiladi.
6.3 Haqiqiy kutubxonalarda
i18next (react-i18next bilan, i18n I) — CustomTypeOptions interfeysi:
// src/turlar/i18next.d.ts
import "i18next";
import type uz from "../tarjimalar/uz.json";
declare module "i18next" {
interface CustomTypeOptions {
defaultNS: "translation";
resources: { translation: typeof uz };
}
}Kalitlar to'g'ridan-to'g'ri uz.json dan olinadi: faylga yangi kalit qo'shsangiz — tur ham yangilanadi. t("menyu.sarlavha") — tekshiriladi (i18n II: type-safe kalitlar).
TanStack Router (TanStack Router) — Register interfeysi, nomi ham bizdagidek:
import { createRouter } from "@tanstack/react-router";
import { routeTree } from "./routeTree.gen";
const router = createRouter({ routeTree });
declare module "@tanstack/react-router" {
interface Register {
router: typeof router;
}
}Shundan keyin <Link to="/menyu/$id"> dagi yo'l, params va qidiruv parametrlari — butun ilova bo'ylab tekshiriladi. Mavjud bo'lmagan sahifaga havola — tsc xatosi. Ikkala kutubxona ham hozir o'rnatilmagan — ularni 19 va 21-qismlarda o'rnatamiz. G'oyasi esa bugungi tarjima.ts bilan bir xil.
Tekshirib ko'ring: Nega kutubxona
Registernitype Register = {}emas,interface Register {}qilib e'lon qiladi?
Javob
declare module ichidagi interface Register { … } asl e'lon bilan birlashishi kerak (declaration merging). type birlashmaydi: ikkinchi type Register — "Duplicate identifier" xatosi. Kengaytirilishi kerak bo'lgan har tur — interface. Kutubxona muallifi foydalanuvchiga "bu yerga varaq qo'shsa bo'ladi" degan eshikni shu bilan qoldiradi.
7. Vazifalar qadami: react-kengaytma.d.ts va commit
7.1 Teg ulushi chizig'i
refactor/turlar ning beshinchi, oxirgi bo'lagi. Yangi fayl src/react-kengaytma.d.ts (kanondan aynan):
// react-kengaytma.d.ts — kutubxona turini kengaytirish (module
// augmentation, 18/#38). React'ning style prop'i (CSSProperties) faqat
// ma'lum CSS xossalarini biladi: style={{ "--ulush": "40%" }} — tsc
// xatosi (o'lchandi, natijalar/38-*). CSS o'zgaruvchilari (custom
// properties) — "--" bilan boshlanadigan har qanday nom; React ularni
// style.setProperty bilan yozadi (CSSOM — CSP style-src'ga tegmaydi).
// "declare module" — @types/react dagi interfeysga yangi a'zo qo'shadi
// (declaration merging), faylning o'zi kod emas
import "react";
declare module "react" {
interface CSSProperties {
[ozgaruvchi: `--${string}`]: string | number | undefined;
}
}Izohdagi bir gapga e'tibor bering: "CSSOM — CSP style-src ga tegmaydi". vazifalar da CSP style-src 'self' — ichki style="…" atributlari taqiqlangan. React esa style prop'ini atribut sifatida emas, element.style.setProperty(…) bilan yozadi. Bu yo'l CSP'ga tushmaydi (CSP). Shuning uchun CSS o'zgaruvchisi vazifalar da xavfsiz.
BatafsilStatistika.tsx dagi ishlatilishi — teg jadvalidagi «bajarildi» katakchasida:
<span
className="ulush"
aria-hidden="true"
style={{
"--ulush": `${Math.round((t.bajarildi / t.jami) * 100)}%`,
}}
/>aria-hidden="true" — chiziq bezak, raqam yonida turibdi. Malika raqamni eshitadi, chiziqni emas (React'da accessibility asoslari). CSS'da chiziq gradient bilan chiziladi:
#batafsil .ulush {
display: block;
height: var(--joy-1);
margin-top: var(--joy-1);
border-radius: var(--joy-1);
background: linear-gradient(
to right,
var(--rang-asosiy) var(--ulush, 0%),
var(--rang-chegara) var(--ulush, 0%)
);
}var(--ulush, 0%) — o'zgaruvchi berilmasa, 0%.
7.2 Tuzoq: test loyihasi .d.ts ni ko'rmadi
Kanonda birinchi npm run tip (tsc -b) yiqildi — xuddi «Nega bu kerak?» bo'limidagi TS2353. Lekin tsc -p tsconfig.app.json — 0 xato. Farq qayerda?
vazifalar da uchta tsconfig loyihasi bor (tsconfig Vite + React loyihada): app, node va test. Testlar src/ dagi komponentlarni import qiladi, demak BatafsilStatistika.tsx test loyihasida ham tekshiriladi. Test loyihasining include ro'yxatida esa global .d.ts fayllar aniq sanalgan edi — yangisi yo'q. «Augmentation butun loyihaga ta'sir qiladi» bo'limidagi qoida aynan shu: kengaytma test loyihasiga kirmadi — u yerda yo'q edi. Tuzatish (kanondan):
// .d.ts — global e'lonlar (import.meta.env, trustedTypes, React style'da
// CSS o'zgaruvchilari — 18/#38): testlar
// import qilgan src/ fayllari ularga tayanadi (17/#28)
"include": [
"tekshiruv/**/*.ts",
"tekshiruv/**/*.tsx",
"src/vite-env.d.ts",
"src/trusted-types.d.ts",
"src/react-kengaytma.d.ts"
]Kanonda bir haqiqat ham yozib qo'yildi: avval bu "TS 7 va TS 6 farqi" deb gumon qilingan edi. Tekshirilganda -p tsconfig.app.json ikkala versiyada ham 0 xato berdi — farq versiyada emas, loyihada edi. Xato sababini taxmin bilan emas, o'lchab topish — shu.
7.3 Commit
Besh darsdagi ish — bitta commit:
git add -A
git commitCommit (kanon): refactor: tsconfig qo'shimcha bayroqlar, Tugma nomi — union, CSSProperties kengaytmasi. Tarkibi:
tsconfig.app.json— uch bayroq (34-dars),tsconfig.test.json—includega yangi.d.ts.ui/Tugma.tsx—Nomiunion'i (37-dars).src/react-kengaytma.d.ts,BatafsilStatistika.tsx,vazifalar.css— teg ulushi chizig'i.
Tekshiruvlar (haqiqiy, natijalar/tekshiruv-38.txt):
npm test— node:testℹ pass 170, VitestTests 45 passed (45).lint,format:check,tip,knip—exit 0.- Build:
dist/assets/index-Cn0-5Xqi.js 257.56 kB │ gzip: 81.84 kB. Turlar build'da yo'qoladi — o'zgarish faqat yangi CSS qoidasi va<span>. - Brauzer tekshiruvi — 159/159, e2e-18 — 50/50.
- Diff: 6 fayl, +68 −8.
Hash sizda boshqacha chiqadi — u fayl tarkibidan hisoblanadi.
8. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
TS7016: Could not find a declaration file |
paketda tur yo'q | @types/… yoki declare module |
import { Activity } — tur xatosi, kod ishlaydi |
@types/react eski |
@types versiyasini react ga moslang |
TS2353 … '"--ulush"' does not exist |
CSSProperties kengaytirilmagan |
react-kengaytma.d.ts |
butun react turi yo'qoldi |
declare module "react" modul bo'lmagan faylda |
faylga import "react" |
tsc -p app — 0, tsc -b — xato |
.d.ts test loyihasi include ida yo'q |
include ga qo'shing |
Duplicate identifier |
type ni birlashtirishga urinish |
interface |
window.x turda bor, ishda undefined |
augmentation qiymat yaratmaydi | qiymatni haqiqatan yozing |
9. Mashqlar
Mashqlar kurs/mashqlar/18/38-kutubxona-turlari/ da.
1-mashq (oson): tur qayerdan?
Har paket uchun turlar qayerdan keladi: paketning o'zi, @types yoki o'z .d.ts?
react—zod(TypeScript'da yozilgan,"types"maydoni bor) —confetti-uz(turlarsiz,@typesham yo'q) —
Yechim
- @types — React JavaScript'da yozilgan, turlari DefinitelyTyped'da (
@types/react). - paketning o'zi —
package.jsondagi"types"tsc'ni.d.tsga yo'naltiradi, alohida paket kerak emas. - o'z .d.ts —
declare module "confetti-uz"bilan, ishlatadigan qismingizni tavsiflab.
2-mashq (o'rta): data-* emas, CSS o'zgaruvchisi
Taomlar reytingi: har taom yonida --yulduz CSS o'zgaruvchisi ("80%" kabi). Komponent Rating({ name, percent }) — <p> ichida nom va <span style={{ "--yulduz": … }}>. Effekt bilan birinchi <span> ning --yulduz qiymatini konsolga chiqaring. Ishora: «React'ning CSSProperties i» bo'limidagi kengaytma.
Yechim
// @ts-options: {"noUnusedParameters": false}
import { useEffect, useRef } from "react";
declare module "react" {
interface CSSProperties {
[ozgaruvchi: `--${string}`]: string | number | undefined;
}
}
type RatingProps = { name: string; percent: number };
function Rating({ name, percent }: RatingProps) {
const style = { "--yulduz": `${percent}%` };
return (
<p>
{name} <span className="yulduz" style={style} />
</p>
);
}
export default function App() {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const span = ref.current?.querySelector("span");
console.log(span?.style.getPropertyValue("--yulduz"));
}, []);
return (
<div ref={ref}>
<Rating name="Osh" percent={80} />
<Rating name="Manti" percent={60} />
</div>
);
}Konsolda:
80%Ekranda:
Osh
MantiBirinchi qatordagi @ts-options — faqat shu dars tekshiruvchisi uchun («Augmentation butun loyihaga ta'sir qiladi» bo'limidagi sabab), o'z loyihangizda kerak emas. Kengaytma bo'lmasa — xato, lekin boshqa raqam bilan: TS2559: Type '{ "--yulduz": string; }' has no properties in common with type 'Properties<…>'. Obyekt alohida o'zgaruvchida bo'lgani uchun tsc "ortiqcha xususiyat" (TS2353) emas, "umumiy xususiyat yo'q" deydi — ma'nosi bir xil. --yulduz ni CSS'da width: var(--yulduz) yoki gradient bilan ishlatasiz. Haqiqiy loyihada kengaytma komponent faylida emas, react-kengaytma.d.ts da bo'ladi.
3-mashq (qiyin): o'z "register" ingiz
«O'z kichik kutubxonamiz» bo'limidagi naqsh bilan buyurtma.ts kutubxonasini yozing: export interface Register {} va holatMatni(holat) funksiyasi. Register da holatlar berilsa — holat faqat shu satrlar, aks holda string. Keyin holatlar.d.ts da "qabul" | "tayyor" | "yetkazildi" ni ro'yxatdan o'tkazing va holatMatni("tayyorr") xato berishini tekshiring. Ishora: Register extends { holatlar: infer H extends string } ? H : string.
Yechim
// buyurtma.ts
export interface Register {}
type Holat = Register extends { holatlar: infer H extends string }
? H
: string;
export function holatMatni(holat: Holat): string {
return `Buyurtma holati: ${holat}`;
}// holatlar.d.ts
import "./buyurtma.ts";
declare module "./buyurtma.ts" {
interface Register {
holatlar: "qabul" | "tayyor" | "yetkazildi";
}
}// ilova.ts
import { holatMatni } from "./buyurtma.ts";
console.log(holatMatni("tayyor")); // Buyurtma holati: tayyor
holatMatni("tayyorr");
// ❌ TS2345: … '"qabul" | "tayyor" | "yetkazildi"'holatlar.d.ts siz Holat — string, ikkala chaqiruv ham o'tadi. U bilan — faqat uchta satr. Uch faylning hammasi tsc'ning bitta loyihasida bo'lishi shart (include) — «Tuzoq: test loyihasi .d.ts ni ko'rmadi» bo'limidagi saboq. Yechim uch faylli loyiha sifatida tsc 7.0.2 bilan tekshirilgan.
4-mashq: Vazifalar qadami
react-kengaytma.d.ts ni qo'shing, BatafsilStatistika ga ulush chizig'ini yozing. Avval kengaytmasiz npm run tip ni ishga tushiring — TS2353 ni ko'ring. Keyin kengaytma bilan — va tsconfig.test.json dagi include ni unutib ko'ring: qaysi buyruq yiqiladi? Hammasini to'g'rilab, commit qiling.
Yechim
- Kengaytmasiz:
tsc—BatafsilStatistika.tsx(…): error TS2353: … '"--ulush"' does not exist in type 'Properties<…>'. - Kengaytma bor,
includeda yo'q:tsc -p tsconfig.app.json— 0 xato,npm run tip(tsc -b) — o'shaTS2353, test loyihasidan. - Ikkalasi to'g'ri:
npm run check— toza (node 170, Vitest 45).npm run build,npm run preview— statistika panelida teg qatorlari ostida chiziq. - Commit —
refactor: tsconfig qo'shimcha bayroqlar, Tugma nomi — union, CSSProperties kengaytmasi. PR'ni birlashtiring.
10. Real ishda
@typesversiyasini kuzatish — Dependabot/Renovatereactva@types/reactni birga yangilashi uchun guruh qoidasi yoziladi (Bog'liqliklarni yangilash).- Augmentation fayllari — har jiddiy loyihada:
env.d.ts,i18next.d.ts,router.d.ts,styled.d.ts(styled-components'ningDefaultThemei ham shunday kengaytiriladi). - "Register" naqshi — TanStack Router, TanStack Query (
Register— xato turi uchun), i18next, Auth.js (Sessionturi). Kutubxona hujjatida "TypeScript" bo'limi deyarli doim shu haqida. - Intervyu savollari: "declaration merging nima?", "
typevainterfaceqachon farq qiladi?" (javob: augmentation), "kutubxonada tur yo'q bo'lsa nima qilasiz?".
Xulosa
- Turlar: paketning o'zidan (
"types"),@types/…(DefinitelyTyped) yoki o'z.d.tsdan; topilmasa —TS7016. @types—devDependenciesda, versiyasi kutubxonaga mos.- Declaration merging — bir nomli
interfacelar qo'shiladi;type— yo'q. declare module "react" { interface CSSProperties { … } }— kutubxona turini kengaytirish; fayl modul bo'lsin (import "react"), loyiha tekshiruviga kirsin.- "Register" naqshi: kutubxona bo'sh interfeys beradi, siz to'ldirasiz — i18next, TanStack Router.
vazifalar:react-kengaytma.d.ts(--ulush), test loyihasiincludetuzog'i, commit — node 170, Vitest 45, brauzer 159/159.
Keyingi dars: React'da accessibility asoslari — semantik teglar, label, aria atributlari va avtomatik tekshiruv.
Manbalar
- TypeScript: Declaration Merging — Module Augmentation, Global augmentation — typescriptlang.org/docs/handbook/declaration-merging.html
- DefinitelyTyped — github.com/DefinitelyTyped/DefinitelyTyped
- Vite: "Env Variables and Modes — IntelliSense for TypeScript" — vite.dev/guide/env-and-mode
- i18next: TypeScript — i18next.com/overview/typescript
- TanStack Router: Type Safety — "Register" — tanstack.com/router/latest/docs/framework/react/guide/type-safety
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!