tslint --project tsconfig.json --config tslint.jsoninterface Animal {
move: number,
}
interface Bird extends Animal {
fly: number,
}
function isBird (animal: Animal): animal is Bird {
return (animal as Bird).fly !== undefined
}
Also:
function isBird (animal: Animal | Bird): animal is Bird {
return (animal as Bird).fly !== undefined
}
NB: The minimum viable example above is derived from an actual use case using LeafletEvent and LeafletMouseEvent from Leaflet. Types defined at DefinitelyTyped.
tslint.json configuration:
{
"rules": {
"strict-type-predicates": true
}
}
tsconfig.json config:
{
"compileOnSave": false,
"compilerOptions": {
"allowJs": false,
"moduleResolution": "node",
"noUnusedLocals": true,
"sourceMap": true,
"strict": true
},
"exclude": [
"node_modules"
],
"include": [
"./src/frontend/**/*",
"./webpack.config.ts"
]
}
$ tslint --project tsconfig.json --config tslint.json
WARNING: /Users/andrew/Development/poc/src/frontend/test.ts[10, 10]: Expression is always true.
I'm still quite new to TypeScript, but given the Advanced Types documentation, I would have expected no error. Apologies if I've misunderstood how this works.
I note similarities with #3222 .
If I remove the type cast, TSLint ceases to complain, but TypeScript begins to throw compilation errors.
// results in: Property 'fly' does not exist on type 'Animal | Bird'. Property 'fly' does not exist on type 'Animal'.
function isBird (animal: Animal | Bird): animal is Bird {
return animal.fly !== undefined
}
This is working as intended. By asserting animal as Bird you tell TypeScript that animal.fly is always a number and never undefined. That's why the rule complains.
You can fix this by using animal as Partial<Bird>.
Most helpful comment
This is working as intended. By asserting
animal as Birdyou tell TypeScript thatanimal.flyis always a number and never undefined. That's why the rule complains.You can fix this by using
animal as Partial<Bird>.