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

Type checking bug (Type 'null' cannot be used as an index type) #20434

Closed
mbrodersen opened this issue Dec 4, 2017 · 2 comments
Closed

Type checking bug (Type 'null' cannot be used as an index type) #20434

mbrodersen opened this issue Dec 4, 2017 · 2 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@mbrodersen
Copy link

mbrodersen commented Dec 4, 2017

TypeScript Version: 2.5.3

Code

if(columnIndex === null) return (_:number) => null;

return (rowIndex:number) => table.rows[rowIndex].rowValues[columnIndex];

Expected behavior:

No type errors.

Actual behavior:

error TS2538: Type 'null' cannot be used as an index type.

(referring to the columnIndex variable captured by the lambda expression)

Work around:

The type error goes away if I instead do:

return (rowIndex:number) => table.rows[rowIndex].rowValues[columnIndex as number];

However that shouldn't be necessary.

@ahejlsberg
Copy link
Member

You didn't post a full example, but I'm assuming columnIndex is a mutable variable (i.e. declared with let or var). If so, the compiler doesn't consider the guard against null to be in effect within the arrow function (because there could have been a subsequent assignment to columnIndex before the arrow function is called).

It should work if you declare columnIndex as const. See #8849 and #10357.

@ahejlsberg ahejlsberg added the Working as Intended The behavior described is the intended behavior; this is not a bug label Dec 4, 2017
@mbrodersen
Copy link
Author

mbrodersen commented Dec 4, 2017

Thanks for the quick reply Anders. Here is the complete example:

export function getTableColumnLookup(column:string, table:Types.Table | null): Types.TableColumnLookup
{
    if(table === null) return (_:number) => null;
    
    let columnIndex = getTableColumnIndex(column, table);
    
    if(columnIndex === null) return (_:number) => null;
    
    return (rowIndex:number) =>
    {
        if(rowIndex < 0 || rowIndex >= table.rows.length) return null;
        
        return table.rows[rowIndex].rowValues[columnIndex];
    }
}

Good point about columnIndex not being const. However the type checker could ideally still infer that columnIndex can not be accessed by anything than the lambda closure (and therefor can not possible be null), given that columnIndex is a primitive type (i.e. not a reference to an object), and the lambda is in a return statement (after which columnIndex goes out of scope). So maybe this is more of a "possible improvement to the type checker" issue then.

@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

2 participants