动态生成类的Typescript接口定义

时间:2019-11-24 11:30:04

标签: typescript interface type-declaration

我做了一些相当“不打字”的事情。我有一个函数,将所有以给定基类的“ _”开头的方法混合到另一个动态创建的类中。

我正在努力定义正确的返回类型。

这里是一个例子:

export interface IConstructable<T>  {
    new(): T;
}

class Foobar {

    _method() {
        console.log('this method should be copied');
    }

    private method() {
        console.log('this method should not be copied');
    }
}

function createHtml (base: IConstructable<unknown>): IConstructable<HTMLElement> {
    class Html extends HTMLElement {
        constructor(){
            super();
        }
    }

    Object.entries(Object.getOwnPropertyDescriptors(base.prototype)).forEach(([name, descriptor]) => {
        if (name.startsWith('_') && typeof descriptor.value === 'function') {
            Object.defineProperty(Html, name, Object.assign({}, descriptor, {
                value(){
                    // some implementation
                }
            }))
        }
    });

    return Html;
}

const HTMLFoobar = createHtml(Foobar);
new HTMLFoobar()._method();

// I want at least the following interface automatically generated
// 
// interface IHTMLFoobar extends HTMLElement, Foobar {
//    
// }
//
// const HTMLFoobar = createHtml(Foobar) as IConstructable<IHTMLFoobar>;
// new HTMLFoobar()._method();

如果这不可能,那么可以通过更改*.d.ts文件以编程方式完成,但是有没有一个项目可以帮助读取和修改/转换*.d.ts文件在这里可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

您可以使用通用类型参数而不是 let ref = Firestore.firestore().collection("messages").order(by: "timestamp", descending: true) ref.addSnapshotListener { (snapshot, error) in snapshot?.documentChanges.forEach({ (diff) in let messageId = diff.document.documentID let messageRef = Firestore.firestore().collection("messages") .document(messageId) messageRef.getDocument(completion: { (document, error) in guard let dictionary = document?.data() as? [String : Any] else { return } let message = Message(dictionary: dictionary) print("we fetched this message \(message.text)") self.messages.append(message) DispatchQueue.main.async { self.collectionView.reloadData() let indexPath = IndexPath(item: self.messages.count - 1, section: 0) self.collectionView.scrollToItem(at: indexPath, at: .bottom, animated: true) } }) }) } 并断言所生成的类是unknown和基数的混合:

HTMLElement

Playground