Issue
I am trying to remove the as
keywords from this typescript code so it can look better. It has this method named update
where I am trying a smarter way to structure the sanitizing, validation and attribution, but it seems that it wouldn't work with typescript, so I am looking for help to implement this while trying the best to maintain the code structure.
This is the code:
export class AccessProfile {
id!: number;
active!: boolean;
name!: string;
createdAt!: Date;
createdBy!: User | null;
createdFrom!: SystemModule;
updatedAt!: Date;
updatedBy!: User | null;
updatedFrom!: SystemModule;
hierarchy!: number | null;
permissions!: Set<string>;
public update(
{
updatedFrom,
updatedBy = null,
name,
active,
hierarchy,
permissions
}: {
updatedFrom: SystemModule,
updatedBy?: DiphycUser | null,
name?: string,
active?: boolean,
hierarchy?: number | null,
permissions?: Set<string>,
}
) {
const changedValues = new Set();
if (name !== undefined) {
name = AccessProfile.sanitizeName(name);
if (this.name !== name) {
AccessProfile.validateName(name);
changedValues.add("name");
}
}
if (active !== undefined && this.active !== active) {
changedValues.add("active");
}
if (hierarchy !== undefined) {
hierarchy = AccessProfile.sanitizeHierarchy(hierarchy);
if (this.hierarchy !== hierarchy) {
AccessProfile.validateHierarchy(hierarchy);
changedValues.add("hierarchy");
}
}
if (
permissions !== undefined
&& !permissionsAreEqual(permissions, this.permissions)
) {
changedValues.add("permissions");
}
if (changedValues.has("hierarchy") && changedValues.has("permissions")) {
AccessProfile.validateHierarchyAndPermissions({
hierarchy: hierarchy as number | null,
permissions: permissions as Set<string>
});
} else if (changedValues.has("hierarchy")) {
AccessProfile.validateHierarchyAndPermissions({
hierarchy: hierarchy as number | null,
permissions: this.permissions
});
} else if (changedValues.has("permissions")) {
AccessProfile.validateHierarchyAndPermissions({
hierarchy: this.hierarchy,
permissions: permissions as Set<string>
});
}
this.updatedFrom = updatedFrom;
this.updatedBy = updatedBy;
if (changedValues.has("name")) this.name = name as string;
if (changedValues.has("active")) this.active = active as boolean;
if (changedValues.has("hierarchy")) this.hierarchy = hierarchy as number | null;
if (changedValues.has("permissions")) this.permissions = permissions as Set<string>;
this.updatedAt = new Date();
return this;
}
}
Solution
I am looking for help to implement this while trying the best to maintain the code structure.
That code would actually benefit from some restructuring: the logical flow is not easy to read and I will simply assume it is correct/exhaustive (as it seems at a cursory read), it is also written in such a way as not to leverage the type guards in TS, which is the very reason why all those type casts are eventually needed.
That said, all uses of as
in that code are to remove undefined
from the type, so, to get rid of those explicit casts while keeping the code structure unchanged, the Non-null Assertion Operator (Postfix !
) might be what you're looking for.
For example:
hierarchy as number | null
becomes:
hierarchy!
Just please NOTE that the !
operator also gets rid of null
, not just of undefined
: so it does the trick in this case, i.e. with this specific function as written, but the "solution" is not robust to changes to the code, since from that point on TS just doesn't see the null
in the type of the interested values -- but not changing the code is one of the two requirements you have given. IOW, it is a minimal hack for a bit more readability, but the advice remains the code better be rewritten to some extent.
Answered By - Julio Di Egidio
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.