I'd like to make it so that my get widget function result automatically returns the specific type based on the parameter I pass to the function. Is there a way to do this in typescript? As of right now it gives me one of the possible types as return but not the specific one corresponding to the key provided.
export interface ExampleAccountCenterHTMLElement extends HTMLElement {
x: () => void;
}
export interface ExampleMiniFooterHTMLElement extends HTMLElement {
y: () => void;
}
enum ExampleHtmlElementsName {
ExampleMiniFooter = 'Example-mini-footer',
ExampleAccountCenter = 'Example-account-center',
}
interface ExampleHtmlElements {
[ExampleHtmlElementsName.ExampleAccountCenter]: ExampleAccountCenterHTMLElement,
[ExampleHtmlElementsName.ExampleMiniFooter]: ExampleMiniFooterHTMLElement,
}
export function getWidget(tagName: ExampleHtmlElementsName) {
return document.querySelector<ExampleHtmlElements[typeof tagName]>(tagName);
}
const res = getWidget(ExampleHtmlElementsName.ExampleAccountCenter)
CodePudding user response:
Using typeof
on tagName
is not a good idea. You gave tagName
the explicit type ExampleHtmlElementsName
, and that is excactly what typeof tagName
will evaluate to. Instead, make the function generic.
export function getWidget<T extends ExampleHtmlElementsName>(tagName: T) {
return document.querySelector<ExampleHtmlElements[T]>(tagName);
}
CodePudding user response:
Yes, you can use a type assertion to specify the return type of your function based on the provided tagName
parameter. You can use the keyof operator to get the type of the keys in the ExampleHtmlElements
interface, and then use this type to access the corresponding value in the ExampleHtmlElements
interface. Here's an example of how you can do this:
export function getWidget(tagName: ExampleHtmlElementsName) {
// Get the type of the keys in the ExampleHtmlElements interface
type ElementKeys = keyof ExampleHtmlElements;
// Use a type assertion to specify the return type based on the provided tagName parameter
return document.querySelector<ExampleHtmlElements[ElementKeys]>(tagName) as ExampleHtmlElements[tagName];
}
In this example, the ElementKeys
type is inferred to be ExampleHtmlElementsName
, and the ExampleHtmlElements[tagName]
expression evaluates to the type corresponding to the provided tagName
value. This allows the compiler to check that the correct type is being returned based on the value of tagName
.