如何将Typescript装饰器用于html标签?

如何将Typescript装饰器用于html标签?,html,typescript,decorator,Html,Typescript,Decorator,我很难理解如何使用Typescript装饰程序。我有以下代码: class Address { private street: string; private city: string; private state: string; private zipCode: string; @displayName("Street") get streetHtml() { return this.street; } @displayName("

我很难理解如何使用
Typescript装饰程序
。我有以下代码:

class Address {
    private street: string;
    private city: string;
    private state: string;
    private zipCode: string;

    @displayName("Street")
    get streetHtml() { return this.street; }

    @displayName("City")
    get cityHtml() { return this.city; }

    @displayName("State")
    get stateHtml()  { return this.state; }

    @displayName("Zip Code")
    get zipCodeHtml() { return this.zipCode; }

    public static map(input: any) {
        let address = new Address();

        address.street = input.street;
        address.city = input.city;
        address.state = input.state;
        address.zipCode = input.zipCode;

        return address;
    }
}

function displayName(name: string) {

    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        let label: HTMLLabelElement = document.createElement('label');

        label.innerHTML = name;

        return label;
    };
}

var address = Address.map({ street: "123 My St", city: "Boise", state: "ID", zipCode: "83709" })

console.log(address.cityHtml);

然而,它唯一要做的就是返回“Boise”。我怎样才能得到装饰师的东西?我确实启用了
“experimentalDecorators”:true
,正如@JohnWhite所评论的那样,在我的
tsconfig

中,类中的getter返回一个字符串(编译器根据返回类型推断出该字符串),但您请求的decorator更改返回一个
htmlabelelement
这可能会在编译时给您带来困难,或者最终导致运行时错误

话虽如此,请回答您的问题:
在decorator中返回的不是访问器的返回值,如下所示:

如果访问器装饰器返回一个值,它将用作 成员的属性描述符

您需要做的是更改“属性描述符”,使其返回所需的值:

function displayName(name: string) {
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
        descriptor.get = () => {
            let label: HTMLLabelElement = document.createElement('label');
            label.innerHTML = name;

            return label;
        }
    };
}
()


编辑 发布我的答案后,我注意到您希望获得:

<label>Boise</label>
()

如有更改:

  • 返回函数现在是一个常规的匿名函数,而不是箭头函数,因此
    this
    将指向类实例而不是窗口
  • 内部html标签现在是
    this[name.toLowerCase()]
    而不是
    name

  • 正如@JohnWhite所评论的,类中的getter返回一个字符串(编译器从返回类型推断出该字符串),但请求修改的decorator返回一个
    htmlabelelement

    这可能会在编译时给您带来困难,或者最终导致运行时错误

    话虽如此,请回答您的问题:
    在decorator中返回的不是访问器的返回值,如下所示:

    如果访问器装饰器返回一个值,它将用作 成员的属性描述符

    您需要做的是更改“属性描述符”,使其返回所需的值:

    function displayName(name: string) {
        return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
            descriptor.get = () => {
                let label: HTMLLabelElement = document.createElement('label');
                label.innerHTML = name;
    
                return label;
            }
        };
    }
    
    ()


    编辑 发布我的答案后,我注意到您希望获得:

    <label>Boise</label>
    
    ()

    如有更改:

  • 返回函数现在是一个常规的匿名函数,而不是箭头函数,因此
    this
    将指向类实例而不是窗口
  • 内部html标签现在是
    this[name.toLowerCase()]
    而不是
    name

  • 您的意思是“Boise”值是您在控制台中看到的唯一值吗?或者你的意思是在页面中?如果是控制台中的一个。这不是因为这是您在console中打印出来的唯一内容吗?为了简化问题,我建议您首先尝试在普通函数上使用decorator,而不是getter。@kucing_terbang他看到了“Boise”,但他希望看到“Boise”。您的意思是“Boise”值是您在console中看到的唯一值吗?或者你的意思是在页面中?如果是控制台中的一个。这不是因为这是您在控制台中打印出来的唯一内容吗?为了简化问题,我建议您首先尝试在普通函数上使用decorator,而不是getter。@kucing_terbang他看到了“Boise”,但他希望看到“Boise”观看。有问题的getter都返回一个
    字符串
    ,这是编译和运行时的预期行为。但是,此装饰器实现将原始返回类型
    string
    替换为
    htmlabelelement
    ,这可能会导致在运行时之前完全隐藏的错误。至少我会发现,要找出一个假定为字符串的变量包含另一种类型的对象的原因很有挑战性,特别是当问题来自隐藏的元编程时。@JohnWhite你完全正确,但这正是OP所要求的。用你的关心更新我的答案。注意。有问题的getter都返回一个
    字符串
    ,这是编译和运行时的预期行为。但是,此装饰器实现将原始返回类型
    string
    替换为
    htmlabelelement
    ,这可能会导致在运行时之前完全隐藏的错误。至少我会发现,要找出一个假定为字符串的变量包含另一种类型的对象的原因很有挑战性,特别是当问题来自隐藏的元编程时。@JohnWhite你完全正确,但这正是OP所要求的。用你的关心更新我的答案。