Reputation: 894
interface Students {
[key:string]: (Student | undefined);
}
interface Student {
age: string;
}
function something (students:Students, student_name:string) {
let student:Student;
if (typeof students[student_name] !== 'undefined')
student = students[student_name]; // Type 'Student | undefined' is not assignable to type 'Student'.
else
return;
}
I often face that situation. Of course, I can use as Student. But, I wanna know if there's a better way.
Upvotes: 1
Views: 54
Reputation: 327634
Usually TypeScript will use control-flow analysis to automatically narrow the type of a value once you have done a check on it. But the problem you're running into is the fact that this narrowing does not happen with bracket-style property accesses (see microsoft/TypeScript#10530) like students[student_name]
. It was addressed for literal index types (see microsoft/TypeScript#26424) such as students["Alice"]
, equivalent to students.Alice
... but to make it work with string
would apparently degrade the compiler performance too much.
The workaround here is to perform the index access just once, and assign the result to a new variable. Then when you check that variable, the control flow analysis should narrow as you want:
function something(students: Students, student_name: string) {
let student: Student;
const maybeStudent = students[student_name]; // Student | undefined
if (typeof maybeStudent !== 'undefined')
student = maybeStudent; // okay, maybeStudent narrowed to Student in check
else
return;
}
Upvotes: 3
Reputation: 821
you can read this; https://mariusschulz.com/blog/typescript-2-0-control-flow-based-type-analysis or this https://www.google.com/search?q=typescript+flow+analysis&oq=typescript+flow+&aqs=chrome.5.69i57j69i60l3j0l2.6090j0j7&sourceid=chrome&ie=UTF-8
it's called flow analysis.
Upvotes: 1