So this is more an open discussion issue than an actual issue/feature request for now 😅 I want to get the ball rolling, and see where you stand on this.
I have migrated my code base to TypeScript in the last few days, and it makes for a smoother dev experience in my opinion, in particular when libraries provide types.
What do you think about providing LocusZoom TypeScript types? Apparently many libraries publish a @types/xxx NPM library, e.g. @types/locuszoom.
Here is a couple of concrete examples where it would be valuable, based on my (very limited, I admit) use of LZ so far:
- a widget (say, set_state) has mandatory and optional arguments, but one needs to refer to the documentation and hope one does not make mistakes (or find out at runtime). Instead, if LZ provides the type, then the developer would instantly know they need to provide
options with the right type, but all other fields would be optional. Something like
interface SetStateWidget {
options: Array<SetStateOptionsConfigField>,
button_html?: string,
button_title?: string,
show_selected?: bool,
state_field?: string,
custom_event_name?: string,
}
interface SetStateOptionsConfigField {
display_name: string,
value: any // or we could even make this interface generic on the type of `value`
}
- one wants to subclass
AssociationLZ but contact a different API which responds in a different format. One thus needs to override _normalizeResponse to adapt back the response to the format of UMich. With a return type in TypeScript, this would make things much simpler!
// In LocusZoom library
interface UMichAssocRow {
analysis: string,
ref_allele_freq?: number,
// etc., maybe also add an index type to accept "any extra field"
}
class AssociationLZ {
// ...
_normalizeResponse(/* ... */): Array<UMichAssocRow> {
// ...
}
}
// In developer code
class CustomAssociationLZ extends AssociationLZ {
_getUrl(/* ... */): string {
return "https://my.custom/api";
}
_normalizeResponse(/* ... */): Array<UMichAssocRow> {
// Here it's much simpler to implement, because TypeScript typechecker gives me errors and hints about the structure I need to return
}
}
I reckon a major drawback is that since there is a significant API surface for LZ, it would take some work to provide the types for all its API. This is the major "problem" in my opinion.
Another con one could argue is that parts of LZ are intrinsically dynamic (e.g. the layout subscription mechanism: it's not really possible to know at compilation time the type of LocusZoom.Layouts.get("foo", "bar")). I don't think this is a real issue: TypeScript typechecker has mechanisms to elegantly step back in those situations, e.g. with any, type casting or index types. 99% of the code would benefit from types, and maybe 1% would not, but would not be blocked either. I think it's ok.
Maybe this could be mitigated by slowly migrating LocusZoom codebase itself to TypeScript? Once LZ is migrated to TS, then it should be a easy - I think - to have/generate its API types and publish to NPM.
So this is more an open discussion issue than an actual issue/feature request for now 😅 I want to get the ball rolling, and see where you stand on this.
I have migrated my code base to TypeScript in the last few days, and it makes for a smoother dev experience in my opinion, in particular when libraries provide types.
What do you think about providing LocusZoom TypeScript types? Apparently many libraries publish a
@types/xxxNPM library, e.g.@types/locuszoom.Here is a couple of concrete examples where it would be valuable, based on my (very limited, I admit) use of LZ so far:
optionswith the right type, but all other fields would be optional. Something likeAssociationLZbut contact a different API which responds in a different format. One thus needs to override_normalizeResponseto adapt back the response to the format of UMich. With a return type in TypeScript, this would make things much simpler!I reckon a major drawback is that since there is a significant API surface for LZ, it would take some work to provide the types for all its API. This is the major "problem" in my opinion.
Another con one could argue is that parts of LZ are intrinsically dynamic (e.g. the layout subscription mechanism: it's not really possible to know at compilation time the type of
LocusZoom.Layouts.get("foo", "bar")). I don't think this is a real issue: TypeScript typechecker has mechanisms to elegantly step back in those situations, e.g. withany, type casting or index types. 99% of the code would benefit from types, and maybe 1% would not, but would not be blocked either. I think it's ok.Maybe this could be mitigated by slowly migrating LocusZoom codebase itself to TypeScript? Once LZ is migrated to TS, then it should be a easy - I think - to have/generate its API types and publish to NPM.