简体   繁体   中英

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" "p-list-view" | "p-grid-view" .

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM