Item 23: Be Consistent in Your Use of Aliases
Aliasing can prevent TypeScript from narrowing types. If you create an alias for a variable, use it consistently.
Be aware of how function calls can invalidate type refinements on properties. Trust refinements on local variables more than on properties.
const place = { name : 'New York' , latLng : [ 41.6868 , - 74.2692 ] } ;
const loc = place . latLng ;
💻 playground
interface Coordinate {
x : number ;
y : number ;
}
interface BoundingBox {
x : [ number , number ] ;
y : [ number , number ] ;
}
interface Polygon {
exterior : Coordinate [ ] ;
holes : Coordinate [ ] [ ] ;
bbox ?: BoundingBox ;
}
💻 playground
function isPointInPolygon ( polygon : Polygon , pt : Coordinate ) {
if ( polygon . bbox ) {
if ( pt . x < polygon . bbox . x [ 0 ] || pt . x > polygon . bbox . x [ 1 ] ||
pt . y < polygon . bbox . y [ 0 ] || pt . y > polygon . bbox . y [ 1 ] ) {
return false ;
}
}
// ... more complex check
}
💻 playground
function isPointInPolygon ( polygon : Polygon , pt : Coordinate ) {
const box = polygon . bbox ;
if ( polygon . bbox ) {
if ( pt . x < box . x [ 0 ] || pt . x > box . x [ 1 ] ||
// ~~~ ~~~ 'box' is possibly 'undefined'
pt . y < box . y [ 0 ] || pt . y > box . y [ 1 ] ) {
// ~~~ ~~~ 'box' is possibly 'undefined'
return false ;
}
}
// ...
}
💻 playground
function isPointInPolygon ( polygon : Polygon , pt : Coordinate ) {
polygon . bbox
// ^? (property) Polygon.bbox?: BoundingBox | undefined
const box = polygon . bbox ;
// ^? const box: BoundingBox | undefined
if ( polygon . bbox ) {
console . log ( polygon . bbox ) ;
// ^? (property) Polygon.bbox?: BoundingBox
console . log ( box ) ;
// ^? const box: BoundingBox | undefined
}
}
💻 playground
function isPointInPolygon ( polygon : Polygon , pt : Coordinate ) {
const box = polygon . bbox ;
if ( box ) {
if ( pt . x < box . x [ 0 ] || pt . x > box . x [ 1 ] ||
pt . y < box . y [ 0 ] || pt . y > box . y [ 1 ] ) { // OK
return false ;
}
}
// ...
}
💻 playground
function isPointInPolygon ( polygon : Polygon , pt : Coordinate ) {
const { bbox} = polygon ;
if ( bbox ) {
const { x, y} = bbox ;
if ( pt . x < x [ 0 ] || pt . x > x [ 1 ] || pt . y < y [ 0 ] || pt . y > y [ 1 ] ) {
return false ;
}
}
// ...
}
💻 playground
const { bbox} = polygon ;
if ( ! bbox ) {
calculatePolygonBbox ( polygon ) ; // Fills in polygon.bbox
// Now polygon.bbox and bbox refer to different values!
}
💻 playground
function expandABit ( p : Polygon ) { /* ... */ }
polygon . bbox
// ^? (property) Polygon.bbox?: BoundingBox | undefined
if ( polygon . bbox ) {
polygon . bbox
// ^? (property) Polygon.bbox?: BoundingBox
expandABit ( polygon ) ;
polygon . bbox
// ^? (property) Polygon.bbox?: BoundingBox
}
💻 playground