TypeScript обеспечивает возможность преобразования AST во время компиляции.
Интересно, можно ли его использовать для безопасного расширения собственных объектов Object, Array, String, не портя его прототипы.
Давайте добавим метод isEmpty()
к Object
, Array
, String
и т. Д. Во-первых, мы разыгрываем TypeScript с ложным объявлением , что такой метод существует:
declare global {
interface Object {
isEmpty(): boolean
}
interface Array {
isEmpty(): boolean
}
interface String {
isEmpty(): boolean
}
}
Затем мы пишем AST-преобразователь , который превращаетэтот код TS мы набираем в редакторе
{ a: 1 }.isEmpty()
[1, 2].isEmpty()
"hello".isEmpty()
В следующий скомпилированный код JS (мы выставляем NativeExtensions
глобально, мы портим глобальную область видимости, но только с этой одной переменной)
NativeExtensions.isEmpty({ a: 1 })
NativeExtensions.isEmpty([1, 2])
NativeExtensions.isEmpty("hello")
И реализация может быть
NativeExtensions.isEmpty = (o) => {
if ('isEmpty' in o) return o.isEmpty()
if (o instanceof Array) return o.length == 0
if (typeof o == 'string' || o instanceof String) return o.length == 0
for (const k in o) if (o.hasOwnProperty(k)) return false
return true
}
Знаете ли вы, возможно ли это, и как написать код TS Transformer, который бы это делал?Может быть, уже есть какие-то усилия в этом направлении?