GeezerVison is showing github.com — type `nothing` emitted in generated .d.ts files · Issue #8345 · microsoft/TypeScript
type nothing emitted in generated .d.ts files #8345Descriptionfunction f() {
var x: string | undefined = undefined;
y = 0;
if (x) {
var y: typeof x;
}
return y; // y has type nothing
}
generates invalid .d.ts file
declare function f(): nothing;
this is a regression introduced by #8340 Activityahejlsberg commented on Apr 28, 2016 I'm tempted to say just don't do that. But I won't. 😉
I definitely don't think the solution is to make nothing a manifest type that you can reference in a type annotation. That leaves rewriting (but to what?) or issuing an error. The error is probably the better option. DanielRosenwasser commented on Apr 28, 2016 I get why {} was not appropriate. But nothing sounds a heck of a lot like what I'd associate void with, so what exactly is the intended difference semantically? mihailik commented on Apr 28, 2016 Can it return any and for those interested in picking at those little tiny details let noImplicitAny generate an error? ahejlsberg commented on Apr 28, 2016 Daniel Rosenwasser (@DanielRosenwasser) There are a couple of important differences between void and nothing.
- The
undefined type is assignable to void, but no types are assignable to nothing.
void can be a constituent of a union type, but nothing disappears in a union type (because it signifies no type at all).
I do agree we have bit of a profusion of nothingness types (undefined, null, void, nothing), but they all have important differences. If anything had to change, we could possibly consider removing the undefined type and having void be the type of the undefined literal. But that would allow silly stuff like assigning the result of a void function to a variable can be undefined, which really should be an error. mhegazy commented on Apr 28, 2016 ContributorAuthor More actions here is a less artificial example:
function bar() {
var x: string | undefined;
if (x) {
return x;
}
throw new Error();
}mhegazy commented on Apr 28, 2016 ContributorAuthor More actions so for .d.ts purposes, should we 1. write void, 2. undefined, 3. nothing and make it legal to name this type. ahejlsberg commented on Apr 28, 2016 (1) and (2) aren't correct and (3) really doesn't help anyone. I think we should (4) issue an error. ahejlsberg commented on Apr 28, 2016 Adding some rationale for (4): There's really no situation ever where you want nothing to be the declared type of an entity. It is typically an indicator of a logic error, but we don't want to eagerly issue the error because you may be writing "defensive" code that deals with incorrect parameters passed from code that doesn't follow the stated contract (such as plain JavaScript). mihailik commented on Apr 28, 2016 function bar() {
throw new Error();
}
Under these reasoning this should produce error too. mhegazy commented on Apr 28, 2016 ContributorAuthor More actions mihailik commented on Apr 28, 2016 Exactly, and that's the same code as in your example (sans no-op if).
Do we end-users of the compiler need this level of precision? By all means it may add value internally, but best reduce peculiarity on the outside, coercing nothing to void or unknown in codegen/diagnostic messages. mhegazy commented on Apr 28, 2016 ContributorAuthor More actions void means it returns no value. nothing means it returned a value, but its type was narrowed down by the compiler to nothing. The assumption is that is never the intention of the user. so if you did not mean for this to happen, so you might want to take a look at the source and see where did the nothing came from, and the error does that.
aluanhaddad commented on Apr 28, 2016
Do we end-users of the compiler need this level of precision? By all means it may add value internally, but best reduce peculiarity on the outside, coercing nothing to void or unknown in codegen/diagnostic messages.
The TypeScript compiler is a TypeScript program so I do not think that would be either possible or valuable.
👍 for making it an error. mihailik commented on Apr 29, 2016 Mohamed Hegazy (@mhegazy) unless this detection generates false positives, as Anders Hejlsberg (@ahejlsberg) pointed out above.
function validateType(val: number | string) {
if (typeof val === 'string') return null;
else {
if (typeof val === 'number') return null;
else return val; // validation fails at runtime, but this code is valid
}
}
function validateTypeMoreDetails(val: number | string) {
if (typeof val === 'string') return null;
else {
if (typeof val === 'number') return null;
else return 'Incorrect type ' + typeof val+' ('+val+')'; // should 'nothing' support plus operator with string?
}
}mihailik commented on Apr 29, 2016 Set theory (empowered by union and intersection types) is bound to produce oddities -- hence a need to limit that power in places where it becomes too exotic and impractical.
Coercing nothing to void or similar may be one of those intentional trivializations for the sake of sanity and practicality. You know saying 'the buck stops with me'? Make that nothing buck stay within the compiler, don't pass it out in the world. DanielRosenwasser commented on Apr 29, 2016 I don't think the nothing type is actually that big of a deal, I just think it's odd to make it an inexpressible type. I don't see a reason to limit users from writing it out like with how null and undefined use to be disallowed. jeffreymorlan commented on Apr 29, 2016
There's really no situation ever where you want nothing to be the declared type of an entity.
A function that always throws an exception, never returning normally, logically has a return value of nothing. Unlike a void-returning function, a nothing-returning function could safely be assigned to any other return type:
function stub() { throw Error("Unimplemented"); }
interface SomeInterface {
someMethod(): number;
someIrrelevantMethod1(): number;
someIrrelevantMethod2(): string;
}
var obj: SomeInterface = {
someMethod() { ... },
someIrrelevantMethod1: stub,
someIrrelevantMethod2: stub
};
Currently this is an error, despite being perfectly type-safe - making stub return nothing would fix that. (Or any, but that makes the type less self-documenting) aluanhaddad commented on Apr 29, 2016 jeffreymorlan perfectly typesafe, but known to produce an error when invoked. mhegazy commented on May 17, 2016 ContributorAuthor More actions ahejlsberg commented on May 18, 2016
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|