TypeScript Version: 3.5.1
Search Terms:
never, generic, generics
Code
let w!: never;
function test<T>(arg: T): void {
console.log('hello')
}
test(w);
My actual use-case:
type Mapper<T, U> = (value: T, index?: number, array?: T[]) => U;
type IsFunction<T> = T extends Function ? T & Function : never;
function toFunction<T, U extends keyof T, V extends IsFunction<T[U]>>(
key: U,
): V extends Function ? Mapper<T, V extends () => infer R ? R : never> : never {
return ((value: T) => (value[key] as V)()) as any;
}
class Test {
x: string;
constructor(x: string) {
this.x = x;
}
getX(): string { return this.x; }
}
const y: Test[] = [new Test('hello')];
y.map(toFunction('x')) // should cause an error
Expected behavior:
I'd expect both of these situations to cause an error
Actual behavior:
No warnings or errors on compilation, even on strict mode.
Yes, never is the bottom type. Just as unknown is a universal receiver, never is a universal producer, so you can assign it to anything.
Equivalently, never is the subtype of every other type (or if you prefer, substitutable for everything else). The empty array [] is of type never[] because you can use it to initialize any other type of array, there are no values so it doesn鈥檛 matter what other type you assign it to.
This is just the nature of a type system with both a top and bottom type. I suspect what you really want in these cases is an invalid type, in which case there鈥檚 another ticket floating around here somewhere about that...
Found it: #23689
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
Most helpful comment
Yes,
neveris the bottom type. Just asunknownis a universal receiver,neveris a universal producer, so you can assign it to anything.Equivalently,
neveris the subtype of every other type (or if you prefer, substitutable for everything else). The empty array[]is of typenever[]because you can use it to initialize any other type of array, there are no values so it doesn鈥檛 matter what other type you assign it to.This is just the nature of a type system with both a top and bottom type. I suspect what you really want in these cases is an
invalidtype, in which case there鈥檚 another ticket floating around here somewhere about that...