Changdae Park
Changdae Park

Reputation: 1079

Define type constraint with the keys of an interface whose type is specific

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

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

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
}

Playground Link

Upvotes: 2

Related Questions