Skip to content

(compiler api) Is it possible variable used before assigned if overridden with non-null operator? #31124

Closed
@bradzacher

Description

@bradzacher

We have a lint rule which attempts to check if a non-null assertion operator is required or not, and warns against the unnecessary operator.

We've essentially got this check in place currently:

const type = checker.getTypeAtLocation(nonNullNode.expression);
if (type === checker.getNonNullableType(type)) {
  reportAndFix('non-null assertion is not required');
}

Which works for every case I can think of, except for the "use before assigned" case.
In that case the type returned by the checker is non-null unless the original variable declaration includes a nullable type.
In this case, the type is considered non null, and the identifier is considered not yet assigned.

Example code:

function testRequired() {
    let resolve: () => void
    new Promise(resolve0 => {
        resolve = resolve0
    })
    return resolve! // this non-null assertion is required, removing it causes compiler to hard fail
}

function testNotRequired() {
    let resolve: () => void = () => {}
    new Promise(resolve0 => {
        resolve = resolve0
    })
    return resolve! // this non-null assertion is not required, removing it is fine
}

I'm trying to figure out if it's possible to detect (using the type checker or similar) that the non-null operator is truly required because the variable is being used before it is assigned.

If we can't detect this case, then we can't provide an autofixer (and I'd really like to provide a fixer), because otherwise in this case we fix to non-compiling code.

related: typescript-eslint/typescript-eslint#453

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions