0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

関数のある引数(プロパティ名)から他のある引数にそのプロパティの型を入れる方法

Posted at

React擬きのJSX関数を作る時のメモです。

どういうことか

create_dom.ts(before)
export const CreateDOM = (tag: string, props: object): HTMLElement => {
    const el = document.createElement(tag);
    switch(tag){
        case "a":
            el.href = props.href;
        case "p":
            el.textContent = props.text;
            break;
        case "img":
            el.src = props.src;
            el.alt = props.alt;
            break;
    }
    return el;
}
index.ts
import { CreateDOM } from "./create_dom.ts";

CreateDOM("p", {text: "aaaa"})
//             ↑ここで型推論したい!!!

1.まず型を定義する

types.ts
export interface ElementProps{
    p: {text: string},
    a: {text: string, href: string},
    img: {src: string, alt: string},
    h2: {text: string}
}

2.型から空の実装(?)を作る

types.ts
export interface ElementProps{
    p: {text: string},
    a: {text: string, href: string},
    img: {src: string, alt: string},
    h2: {text: string}
}
//型を決めておく(ここ重要、XX|undefinedや?が効かなくなる。)
export const ImplementElementProps: ElementProps = {
    p: {text: ""},
    a: {text: "", href: ""},
    img: {src: "", alt: ""},
    h2: {text: ""}
}

2.プロパティ名になる部分をジェネリックにする

create_dom.ts(after)
import { type ElementProps, ImplementElementProps } from "./types.ts";
export const CreateDOM = <K extends keyof ElementProps>(tag: K, props: typeof ImplementElementProps[K]): HTMLElement => {
    const el = document.createElement(tag);
    switch(tag){
        case "a":
            el.href = props.href;
        case "p":
        case "h2"
            el.textContent = props.text;
            break;
        case "img":
            el.src = props.src;
            el.alt = props.alt;
            break;
    }
    return el;
}

解説(適当)

ジェネリックで前もってkeyofにして引数の型を固定しておけば型がしっかりすると思われる。
propsの部分はtypeofから変数を参照してtagをプロパティ名として使えるようにして[]でアクセスし型を取得できていると思われる。

TypeScriptの複雑な型の解決は難しいが解決出来た瞬間が非常に気持ちいいのである。Microsoftは神。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?