Excess Property Checks یا بررسی پراپرتی اضافی
مثال زیر را به عنوان Interface و متد زیر را در نظر بگیرید.interface Point {
x: number;
y?: number;
}
function computeDistance(point: Point) { /*...*/ }
computeDistance
(
{ x: 1
, y: 2, z:
3
});
// Object literal may only specify known properties, and 'z' does not exist in type 'Point'.(2345)
computeDistance({ x: 1, y: 2, z: 3 });
// Object literal may only specify known properties, and 'z' does not exist in type 'Point'.(2345)
const obj = { x: 1, z: 3 };
computeDistance(obj); // OK
Excess Property Checks یا بررسی پراپرتی اضافی چه کمکی میکند؟
زمانی که ورودی یک متد را با یک متغیر که بصورتهای مختلف در برنامه ایجاد میشود مقداردهی میکنیم Opened interpretation رخ میدهد و بررسی وجود پراپرتی اضافی بررسی نمیشود ولی در حالتی که خودمان بصورت یک Object literal به عنوان ورودی تابع در نظر میگیریم Closed interpretation رخ میدهد و اگر در زمان نوشتن پراپرتیهای آبجکت خطای تایپی رخ دهد که در این حالت احتمال بیشتری دارد تایپ اسکریپت آن را به عنوان یک پراپرتی اضافی در نظر گرفته و هشدار میدهد.مثال زیر را در نظر بگیرید:
interface Person {
first: string;
middle?: string;
last: string;
}
function computeFullName(person: Person) { /*...*/ }
computeFullName({first: 'Jane', mdidle: 'Cecily', last: 'Doe'});
// @ts-ignore: Argument of type '{ first: string; mdidle: string; last: string; }' is not assignable to parameter of type 'Person'.
// Object literal may only specify known properties, but 'mdidle' does not exist in type 'Person'. Did you mean to write 'middle'?
middle
عبارت mdidle
را تایپ کردیم نمایش داده میشود.
روشهای جلوگیری از بررسی وجود پراپرتیهای اضافی
۱ـ استفاده از یک متغیر واسط برای مقداردهی به متد یک تابعconst obj = { x: 1, y: 2, z: 3 };
computeDistance1(obj);
computeDistance1({ x: 1, y: 2, z: 3 } as Point); // OK
function computeDistance2<P extends Point>(point: P) { /*...*/ }
computeDistance2({ x: 1, y: 2, z: 3 }); // OK
interface Person {
first: string;
middle?: string;
last: string;
// Index signature
[propName: string]: any;
}
interface Incrementor {
inc(): void
}
function createIncrementor(start = 0): Incrementor {
return {
// @ts-ignore: Type '{ counter: number; inc(): void; }' is not assignable to type 'Incrementor'.
// Object literal may only specify known properties, and 'counter' does not exist in type 'Incrementor'.(2322)
counter: start,
inc() {
// @ts-ignore: Property 'counter' does not exist on type 'Incrementor'.(2339)
this.counter++;
},
};
}
function createIncrementor2(start = 0): Incrementor {
return {
counter: start,
inc() {
// @ts-ignore: Property 'counter' does not exist on type 'Incrementor'.(2339)
this.counter++;
},
} as Incrementor;
}
function createIncrementor3(start = 0): Incrementor {
const incrementor = {
counter: start,
inc() {
this.counter++;
},
};
return incrementor;
}
interface Incrementor {
inc(): void;
[propName: string]: any;
}