2021年6月17日木曜日

(new Date)['get' + 'Month']()みたいな方法はTypeScriptではできないっぽい

JavaScriptではできましたが、TypeScriptでは駄目なようです。
ブラウザによって違うのかもしれませんが、少なくともDenoは受け入れてくれませんでした。



日時を取得する関数を以下のように定義して
function forIn(obj:any, fun:any){
for(const name in obj){
const v = fun(name, obj[name])
if(v){return v}
}
}
function get日時(dt:Date = new Date()) {
const f = (num:number, 桁数:number) => { return ('000' + num).slice(-桁数) }
const obj = {
FullYear : 4,
Month : 2,
Date : 2,
Hours : 2,
Minutes : 2,
Seconds : 2,
Milliseconds : 3
}
const 間 = '// ::: '.split('')
let str出力 = ''
forIn(obj, (name:string, 桁数:number)=>{
str出力 += f(dt['get'+name]() + (name=='Month'?1:0), 桁数) + 間.shift()
})
return str出力.slice(0, str出力.length-1)
}
if(import.meta.main){
console.log('[[['+get日時()+']]]')
}
view raw ng.ts hosted with ❤ by GitHub



denoで実行したらエラーになりました



仕方がないのでevalに変えたら動作しました。
function forIn(obj:any, fun:any){
for(const name in obj){
const v = fun(name, obj[name])
if(v){return v}
}
}
function get日時(dt:Date = new Date()) {
const f = (num:number, 桁数:number) => { return ('000' + num).slice(-桁数) }
const obj = {
FullYear : 4,
Month : 2,
Date : 2,
Hours : 2,
Minutes : 2,
Seconds : 2,
Milliseconds : 3
}
const 間 = '// ::: '.split('')
let str出力 = ''
forIn(obj, (name:string, 桁数:number)=>{
str出力 += f(eval('dt.get'+name+'()') + (name=='Month'?1:0), 桁数) + 間.shift()
})
return str出力.slice(0, str出力.length-1)
}
if(import.meta.main){
console.log('[[['+get日時()+']]]')
}
view raw ok.ts hosted with ❤ by GitHub






今回のように「日時を文字列化する」という目的なら他の解決策もありますが、それ以外のケースでこの手法が使えなくて困る場合が、もしかしたら、あるかも…。
…と、思いましたが、これは所謂バッドノウハウというヤツなのかもしれません。
実行時まで呼び出される関数が何だか分からないから型チェックもできなくなっちゃいますし。

0 件のコメント:

コメントを投稿