- Bendera ketat termasuk bendera berikut:
--strictNullChecks--alwaysStrict--noImplicitAny--noImplicitThis--strictBindCallApply--strictFunctionTypes--strictPropertyInitializationKami memberikan contoh dan mencoba memahami di satu tempat apa arti semua ini.// I. --strictNullChecks
Masalah terkenal dengan NPE (pengecualian pointer nol, kesalahan miliar dolar) dalam konteks TS.Secara default, dalam TS semua jenis adalah Nullable dan ini berarti bahwa kita dapat melewati "undefined" | "Null" di mana jenis lain diharapkan (bahkan primitif):const bar1: { foo: number } = undefined;
const bar2: { foo: number } = null;
const bar3: number = null;
const bar4: string = null;
Contoh yang lebih menarik adalah pemanggilan metode, yang mungkin tidakdeclare var smth: { optionalMethod?(): string; };
smth.optionalMethod();
Juga tersirat bahwa kita tidak dapat mengembalikan "tidak terdefinisi" | "Null" di mana ini jelas tidak diharapkanfunction getIt(): { data: number } {
return undefined;
}
getIt().data;
Kami harus secara eksplisit menunjukkan bahwa "tidak terdefinisi" dapat kembali dan hanya setelah itu kami mendapatkan kesalahanfunction getIt(): { data: number } | undefined {
return undefined;
}
getIt().data;
Dan sebagai bonus - operasi yang lebih aman, di mana mungkin tidak ada hasil, akan ada kesalahan dengan bendera dihidupkan dan Anda harus secara eksplisit memeriksa bahwa "menemukan" menemukan sesuatu:
[{ name: 'John', age: 4 }]
.find(el => el.age === 42)
.name;
// II. --selalu ketat
Menambahkan anotasi 'gunakan ketat' ke setiap file, menjadikan perilaku JS lebih eksplisit// AKU AKU AKU. --noImplicitAny
Melarang penggunaan 'apa pun' secara implisit dalam TS, mis. kode tanpa jenis anotasi
function id(arg) {
return arg;
}
Ini sangat membantu dengan impor yang tidak diketik dari perpustakaan pihak ketiga, menawarkan untuk menginstal definisi tipe
import * as session from '3rd-party-lib';
// IV. --strictBindCallApply
Ini mencakup pemeriksaan jenis "lebih ketat" untuk "bind" / "panggilan" / "berlaku", tanpa bendera - ini semua adalah TS yang valid. function getFullName(name: string, surname: string): string {
return name + surname;
}
getFullName.call(null, 'John', 42);
getFullName.apply(null, ['John', 42]);
getFullName.bind(null)('John');
getFullName.bind(null, 'John')();
getFullName.bind(null, 'John')(42);
// V. --strictPropertyInitialization + --strictNullChecks
Membantu melacak bahwa semua properti telah diinisialisasi dalam konstruktor, Anda juga harus mengaktifkan --strictNullChecks untuk menonaktifkan tipe Nullable. class User {
name: string;
}
Namun, jika tugasnya tidak ada di konstruktor itu sendiri, yakinkan TS bahwa semuanya baik-baik saja. class User2 {
name: string;
constructor(name: string) {
this.initializeName();
}
initializeName() {
this.name = 'John'
}
}
Jika Anda tidak dapat meyakinkan TS bahwa properti tersebut akan diinisialisasi dengan tepat, Anda dapat mengatakan "Saya bersumpah demi Ibu, saya pasti akan menginisialisasi!" atau lebih singkat β!βclass User3 {
name!: string;
}
// VI. --strictFunctionTypes
Menghapus cek bivariat untuk argumen.Variandalam pemrograman, singkatnya - ini adalah kemampuan untuk melewati Supertype / Subtype di sana, di mana Type diharapkan. Misalnya, ada hirarki Shape -> Circle -> Rectangle, apakah mungkin untuk mentransfer atau mengembalikan Shape / Rectangle jika Circle diharapkan ? OpsiPemrograman habr , SOinterface Shape { name: string };
interface Circle extends Shape { width: number };
interface Rectangle extends Circle { height: number };
declare var logSC: (figure: Shape) => Circle;
declare var logRC: (figure: Rectangle) => Circle;
declare var logCC: (figure: Circle) => Circle;
declare var logCS: (figure: Circle) => Shape;
declare var logCR: (figure: Circle) => Rectangle;
declare var wlogBB: (fn: (figure: Circle) => Circle) => void;
wlogBB(logCC);
wlogBB(logSC);
wlogBB(logCR);
wlogBB(logCS);
wlogBB(logRC);
Dipahami bahwa fungsi tidak boleh mengubah argumen yang dilewati (bertindak sebagai produsen tipe), tidak ada kesalahan dalam TS, pada kenyataannya - adaconst squares: Square[] = [{ name: 'Square', width: 5 }];
function addSmth(arg: Shape[]) {
arg.push({ name: 'Square' });
}
addSmth(squares);
// VII. --tidak terapkan Ini
Jika fungsi didefinisikan di luar objek / kelas, maka TS akan meminta Anda untuk secara eksplisit menunjukkan apa "ini" akan merujuk menggunakan pseudo-argumen pertama bernama "ini"
function getName(this: { name: string }, surname: string): string {
return this.name;
}
getName.call({}, 'Smith');
getName.apply({}, ['Smith']);
getName.bind({})('Smith');
Panggilan akan validconst somePerson = { name: 'John', getName };
const fullName: string = somePerson.getName('Smith')
getName.call({name: 'John'}, 'Smith');
getName.apply({name: 'John'}, ['Smith']);
getName.bind({name: 'John'})('Smith');
Fungsi Konstruktor Dapat Memberikan Masalahfunction Person(this: { name: string }, name: string) {
this.name = name;
}
const person = new Person('John');
Bonus yang menarik adalah menambahkan perbandingan metode pengikatan konteks untuk kelas.class A {
x = 42;
constructor() {
this.getBound = this.getBound.bind(this);
}
getSimple(): number {
return this.x;
}
getSimpleAnnotated(this: A): number {
return this.x;
}
getArrow = (): number => this.x;
getBound(this: A): number {
return this.x;
}
}
const a = new A();
const getSimple = a.getSimple;
getSimple();
const getSimpleAnnotated = a.getSimpleAnnotated;
getSimpleAnnotated();
const getArrow = a.getArrow;
getArrow();
const getBound = a.getBound;
getBound();