In @types/phantom, there is a WebPage interface, which includes the following function:
interface WebPage {
// ...
property(
key:
| "content"
| "plainText"
| "focusedFrameName"
| "frameContent"
| "frameName"
| "framePlainText"
| "frameTitle"
| "libraryPath"
| "offlineStoragePath"
| "title"
| "url"
| "windowName",
): Promise<string>;
}
I'm trying to extract the property of "key" and use it in a generic.
I'm expecting the following:
async getPageProperty<T extends Parameters<WebPage["property"]>[0]>(url: string, property: T){
// ...
}
to interpret the the "key" argument's type as "content" | "plainText" | "focusedFrameName" | ...
, but, to my surprise, I get:
(type parameter) T in PhantomJS.getPageProperty<T extends string>(url: string, property: T): Promise<T>
.
Is there any way to correctly type T as the string literal instead of just "string" ?
What you did is correct if that were the only signature of the function. The problem is that the types for phantom have multiple overloads for property
, not just the one that you provide. Thus, the extracted type is the union of all of those possible types of key
, and some of them have key
as simply string
.
property(key: "framesName" | "pagesWindowName" | "pages"): Promise<string[]>;
property(key: "canGoBack" | "canGoForward" | "navigationLocked" | "ownsPages"): Promise<boolean>;
property(key: "framesCount" | "offlineStorageQuota" | "zoomFactor"): Promise<number>;
property(key: "clipRect"): Promise<{
top: number;
left: number;
width: number;
height: number;
}>;
property(key: "cookies"): Promise<ICookie[]>;
property(key: "customHeaders"): Promise<{ [key: string]: string }>;
property(key: "paperSize"): Promise<IPaperSizeOptions>;
property(key: "scrollPosition"): Promise<{ top: number; left: number }>;
property(key: "viewportSize"): Promise<{ width: number; height: number }>;
property<T>(key: string): Promise<T>;
property<T>(key: string, value: T): Promise<void>;