So lets's say I have
declare function doSomething(...args: any[]): any
interface Example {
a: number
b: number
}
doSomething({a: 2, b: 1, c: 10} as Example)
This does not report an error as that object extends Example and typescript is happy, so I end up using an ugly identity function:
function cast<T>(arg: T) {
return arg
}
doSomething(cast<Example>({a: 2, b: 1, c: 10})) // yay, error
It irritates the heck out of me that I need to actually call an %^#% no-op function just to do a proper type cast. I end up declaring it in every file that needs it just to give the js compiler better chances of optimizing it out.
Is there any ts magic I don't know about that can avoid the function call?
And yes, I know I can do this:
const x: Example = {a: 2, b: 1, c: 10}
doSomething(x)
and this:
declare function doSomething(arg: Example): any
that's really not the point here. Consider the following lambda:
const example = (i: number, j: number, k: number) => cast<Example>({a: 1, b: 2, c: 3})
to properly set the type without resulting to the identity function I would need to write
const example: (i: number, j: number, k: number) => Example = (i, j, k) => ({a: 1, b: 2, c: 3})
which is no very DRY
And yes, I can just write
function example (i: number, j: number, k: number): Example {
return {a: 1, b: 2, c: 3}
}
again, not the point
// edit
as @thedude just blew my mind in the comment with the lambda return typeing syntax I did not know about, one more example where I use this casting
declare function doSomethingWithArray(arg: Example[]): void
doSomethingWithArray(cast<(Example | boolean)[]>([
{a: 1, b: 2},
false,
{a: 1, b: 2, c: 3}
]).filter(x => x) as Example[])
// edit 2
as it seems I ma terrible at explaining what I want, another example: this generic function solves the filter example-problem
function filterFalse<T>(x: (T | false)[]) {
return x.filter(x => x) as Exclude<T, false>[]
}
doSomethingWithArray(filterFalse<Example>([
{a: 1, b: 2},
false,
{a: 1, b: 2, c: 3} // error
]))
but requires defining a specialized function just for this specific task. I am asking if there is a generic way to force a strict type check on a compile-time literal without resulting to a function call. So exactly what cast<T> does but without the pointless call in the js output.
const example = (i: number, j: number, k: number): Example => ({a: 1, b: 2, c: 3})any, then you should very rarely need to do casting like this.castfunction. Thefilterfunction can act on any array, so you can give it an array of mixed booleans andExampleobjects. Typescript will already infer that the type of that array is(boolean | Example)[].doSomethingWithArray([{a: 1, b: 2, c: 3}].filter(x => x))does not fail on thec, while without the filter it does.