I have TS2532: Object is possibly 'undefined' when I try to find an object's value by dynamically selecting the key. For some reason, typescript doesn't allow me to check the values of the field and I'm not sure what the reason is. Check the code below, please!
import {calculateAge} from "../helpers/ageCalculator";
export class EmployeeModel {
id: number;
first_name: string;
last_name: string;
birthdate: string;
email: string;
gender: string;
department: string;
age?: number = 0;
constructor(employee: EmployeeModel = {} as EmployeeModel) {
this.id = employee.id;
this.first_name = employee.first_name;
this.last_name = employee.last_name;
this.birthdate = employee.birthdate;
this.email = employee.email;
this.gender = employee.gender;
this.department = employee.department;
this.age = calculateAge(employee.birthdate);
}
export const useGetEmployees = () => {
const [searchParams] = useSearchParams();
const sortBy = searchParams.get('sortBy');
const direction = searchParams.get('direction');
const compareFunc = (a:EmployeeModel, b: EmployeeModel) => {
let sortResult = 0;
if (a === undefined && b === undefined) {
return 0;
}
//TS2532: Object is possibly 'undefined'.
if (a[sortBy as keyof EmployeeModel] < b[sortBy as keyof EmployeeModel]){
sortResult = -1;
}
//TS2532: Object is possibly 'undefined'.
if ( a[sortBy as keyof EmployeeModel] > b[sortBy as keyof EmployeeModel] ){
sortResult = 1;
}
else return sortResult;
return direction === SortDirection.Desc ? -sortResult : sortResult;
};
const { data, isLoading, status } = useQuery('employeeList', getEmployeeList, {
select: (employees: EmployeeModel[]) => employees.map(
(employee: EmployeeModel) => {
return new EmployeeModel(employee);
}
).sort(compareFunc),
});
return {employees: data, isLoading, status} as const;
}
export const calculateAge = (birthdate: string) : number => {
const currentDate = new Date();
const currentYear = currentDate.getFullYear();
const birthDate = new Date(birthdate);
const birthYear = birthDate.getFullYear();
return currentYear - birthYear;
}
UPD: Added calculateAge() code
CodePudding user response:
Your main problem comes from age?
. It could be undefined and as such any access to a EmployeeModel
via a key string could be undefined.
You have a few options here:
- define
age
asnumber
:age: number
, but I don't know howcalculateAge
looks like. - get the values from
a[key]
andb[key]
and check them for undefined. - exclude
age
from the list of keys.
const key: Exclude<keyof EmployeeModel, "age"> = sortBy as Exclude<keyof EmployeeModel, "age">
if (key) {
if (a[key] < b[key]){
sortResult = -1;
}
if ( a[key] > b[key] ){
sortResult = 1;
}
}
A few notes:
- this check
if (a === undefined && b === undefined)
is not needed. - I would create a key value at the top and reuse it. Something like this
const key: = sortBy as keyof EmployeeModel
if (key) {
if (a[key] < b[key]){
sortResult = -1;
}
if ( a[key] > b[key] ){
sortResult = 1;
}
}