Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion: Let null assertion (!) operator block "used before assigned" errors #11463

Closed
ghost opened this issue Oct 8, 2016 · 3 comments
Closed
Labels
Fixed A PR has been merged for this issue Help Wanted You can do this Suggestion An idea for TypeScript

Comments

@ghost
Copy link

ghost commented Oct 8, 2016

TypeScript Version: nightly (2.1.0-dev.20161008)

Code

(Compile with --strictNullChecks)

let n: number
doit(() => {
    n = 0
})
n! + 1

function doit(action) { action() }

Expected behavior:

No error

Actual behavior:

a.ts(5,1): error TS2454: Variable 'n' is used before being assigned.

The problem is fixed by using let n: number | undefined, but it's not obvious that that's the solution, and it would be intuitive for the ! operator to work in this situation.

Aside: I don't see the ! operator documented in the handbook.

@kitsonk
Copy link
Contributor

kitsonk commented Oct 9, 2016

Yes, some solution to immediately invoked callbacks would be great. @novemberborn and others have had issues trying to convert a Promise into a deferral and we have had to actually assign noop functions to values to work around the CFA. For example:

const noop = () => { };

function createDeferral() {
    let complete = noop;
    let cancel = noop;
    const promise = new Promise<void>((resolve, reject) => {
        complete = resolve;
        cancel = reject;
    });

    return { complete, cancel, promise };
}

const deferral = createDeferral();

Which sort of seems silly. I assume we would rewrite it as this with this proposal:

function createDeferral() {
    let complete: () => void;
    let cancel: () => void;
    const promise = new Promise<void>((resolve, reject) => {
        complete = resolve;
        cancel = reject;
    });

    return { complete!, cancel!, promise };
}

const deferral = createDeferral();

I also second the "undocumented" nature of !. Several of the team found it by accident by searching issues.

@kitsonk
Copy link
Contributor

kitsonk commented Oct 11, 2016

As I mentioned in #11498 I am more supportive of an annotation that indicates that the function is immediately invoked than this solution.

@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this and removed In Discussion Not yet reached consensus labels Oct 31, 2016
@RyanCavanaugh RyanCavanaugh assigned ghost Oct 31, 2016
@RyanCavanaugh
Copy link
Member

Approved since "not assigned yet" is really the same thing as "still has undefined in its domain"

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Fixed A PR has been merged for this issue Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants