Reputation: 1079
Let me clear the question. I have an interface whose keys are tag names and the type of each key is the corresponding custom element class.
// custom element class
class View extends HTMLElement { ... }
abstract class ScrollLayout extends View { ... }
class ListView extends ScrollLayout { ... }
class GridView extends ScrollLayout { ... }
// Tag to Class
interface Tag2Class {
"p-view": View;
"p-list-view": ListView;
"p-grid-view": GridView;
}
Now, I want to define another interface that has a key named layout
whose type is the key of Tag2Class
typed ScrollLayout
interface Attrs {
layout?: ??? // I want the type to be "p-list-view" | "p-grid-view" | undefined
}
Is there a way to implement this? I tried Record<>
interface Attrs {
layout?: keyof Record<keyof Tag2Class, ScrollLayout>;
}
But strangely, the type of layout
also contains "p-view"
. I don't understand why the result came out like that because the Record type above would return the type { [P in keyof Tag2Class]: ScrollLayout }
, and the keyof this would be only "p-list-view" | "p-grid-view"
.
Upvotes: 0
Views: 687
Reputation: 249636
You can use the KeyOfType
from here to filter keys of a specific type:
type KeyOfType<T, U> = { [P in keyof T]: T[P] extends U ? P : never }[keyof T]
interface Attrs {
layout?: KeyOfType<Tag2Class, ScrollLayout> // "p-list-view" | "p-grid-view" | undefined
}
Upvotes: 2