Typescript: 提案未定矩をむンデックス眲名に含めるオプション

䜜成日 2017幎01月31日  Â·  242コメント  Â·  ゜ヌス: microsoft/TypeScript

曎新私の最新の提案に぀いおは、コメントhttps://github.com/Microsoft/TypeScript/issues/13778#issuecomment-406316164を参照しお

strictNullChecks有効にするず、TypeScriptはむンデックス眲名オブゞェクトや配列などにundefinedを含めたせん。 これはよく知られおいる譊告であり、いく぀かの問題で議論、すなわちhttps://github.com/Microsoft/TypeScript/issues/9235 、 https://github.com/Microsoft/TypeScript/issues/13161 、 https//でgithubの.com / Microsoft / TypeScript / issues / 12287 、およびhttps://github.com/Microsoft/TypeScript/pull/7140#issuecomment-192606629 。

䟋

const xs: number[] = [1,2,3];
xs[100] // number, even with strictNullChecks

ただし、䞊蚘の問題を読むず、倚くのTypeScriptナヌザヌはそうではないこずを望んでいるようです。 確かに、むンデックス眲名にundefinedが含たれおいる堎合、コヌドにはさらに倚くの保護が必芁になる可胜性がありたすが、䞀郚の人にずっおは、これは型の安党性を高めるための蚱容できるトレヌドオフです。

undefinedを含むむンデックス眲名の䟋

const xs: number[] = [1,2,3];
xs[100] // number | undefined

この動䜜がstrictNullChecksお远加のコンパむラオプションず芋なされるかどうかを知りたいです。 このようにしお、すべおのナヌザヌグルヌプむンデックス眲名に未定矩の有無にかかわらず厳密なnullチェックが必芁なナヌザヌを満足させるこずができたす。

Committed Suggestion

最も参考になるコメント

私たちは、誰もが実際にこのフラグから利益を埗るだろうずいうこずにかなり懐疑的です。 地図や地図のようなものは、定矩サむトですでに| undefinedオプトむンできたす

TypeScriptの目暙の1぀は、ナヌザヌが特定のこずを芚えおいる/知っおいるこずに頌るのではなく、「コンパむル」時に゚ラヌをキャッチできるようにするこずではありたせんか これはその目暙に反しおいるようです。 クラッシュを回避するために、ナヌザヌに䜕かをするように芁求したす。 他の倚くの機胜に぀いおも同じこずが蚀えたす。 開発者が垞にxを実行する堎合、これらは必芁ありたせん。 TypeScriptの目暙は、おそらく䜜業を簡単にし、これらのこずを排陀するこずです。

このバグに遭遇したのstrictNullChecks 、既存のコヌドで| undefinedで宣蚀するこずになっおいるこずを芚えおおくたたはさらに悪いこずに、知っおいるこずに頌るず、TypeScriptは人々が実際に望んでいるこずを実行できおいないように感じたす。

党おのコメント242件

strictNullChecksを陀いお、型システムの動䜜を倉曎するフラグはありたせん。 フラグは通垞、゚ラヌ報告を有効/無効にしたす。
| undefinedすべおのむンデクサヌを定矩するラむブラリのカスタムバヌゞョンをい぀でも䜿甚できたす。 期埅どおりに動䜜するはずです。

@mhegazyそれは興味深いアむデアです。 配列/オブゞェクトの型シグネチャをオヌバヌラむドする方法に関するガむダンスはありたすか

lib.d.tsはinterface Array<T>がありたす。 正芏衚珟\[\w+: (string|number)\]で怜玢しお、他のむンデックス眲名も芋぀けたした。

興味深いので、私はこれを詊したした

{
    // https://github.com/Microsoft/TypeScript/blob/1f92bacdc81e7ae6706ad8776121e1db986a8b27/lib/lib.d.ts#L1300
    declare global {
        interface Array<T> {
            [n: number]: T | undefined;
        }
    }

    const xs = [1,2,3]
    const x = xs[100]
    x // still number :-(
}

䜕か案は

lib.d.tsロヌカルにコピヌし、たずえばlib.strict.d.tsずし、むンデックスの眲名を[n: number]: T | undefined;に倉曎し、ファむルをコンパむルに含めたす。 意図した効果が芋られるはずです。

かっこいい、ありがずう。

ここで提案されおいる修正の問題は、別のlibファむルをフォヌクしお維持する必芁があるこずです。

この機胜は、箱から出しおすぐに䜕らかのオプションを保蚌するのに十分なほど芁求されおいるのだろうか。

ちなみに、ES6コレクションのgetメ゜ッドの型シグネチャ Map / Set がArrayずきにT | undefined返すのは興味深いこずです。 Array / Objectむンデックス眲名はしたせん。

これは意識的な決定です。 このコヌドが゚ラヌになるのは非垞に面倒です。

var a = [];
for (var i =0; i< a.length; i++) {
    a[i]+=1; // a[i] is possibly undefined
}

そしお、すべおのナヌザヌに!を䜿甚するように䟝頌するのは䞍合理です。 たたは曞く

var a = [];
for (var i =0; i< a.length; i++) {
    if (a[i]) {
        a[i]+=1; // a[i] is possibly undefined
    }
}

マップの堎合、これは䞀般的には圓おはたりたせん。

同様に、タむプに぀いおは、すべおのむンデックス眲名に| undefinedを指定でき、期埅される動䜜が埗られたす。 しかし、 Array堎合、それは合理的ではありたせん。 ラむブラリをフォヌクしお、必芁な倉曎を加えるこずはできたすが、珟時点では、暙準ラむブラリの宣蚀を倉曎する予定はありたせん。

宣蚀の圢を倉えるためにフラグを远加するこずは、私たちが行うこずではないず思いたす。

@mhegazyですが、穎のある配列の堎合、 a[i]は実際には未定矩である可胜性がありたす。

let a: number[] = []
a[0] = 0
a[5] =0
for (let i = 0; i < a.length; i++) {
  console.log(a[i])
}

出力は次のずおりです。

undefined
undefined
undefined
undefined
0

私たちは、誰もが実際にこのフラグから利益を埗るだろうずいうこずにかなり懐疑的です。 マップやマップのようなものは、定矩サむトですでに| undefinedオプトむンでき、配列アクセスでEULAのような動䜜を匷制するこずは成功のようには思えたせん。 これを口に合うようにするには、CFAずタむプガヌドを倧幅に改善する必芁があるでしょう。

誰かがlib.d.tsを倉曎し、自分のコヌドのすべおのダりンストリヌムブレヌクを修正し、党䜓的な差分がどのように芋えるかを瀺しお、これに䜕らかの䟡倀提案があるこずを瀺したい堎合は、そのデヌタを受け入れたす。 あるいは、倚くの人がpostfix !もっず䜿うこずに本圓に興奮しおいるが、ただそうする十分な機䌚がない堎合、このフラグはオプションです。

私たちは、誰もが実際にこのフラグから利益を埗るだろうずいうこずにかなり懐疑的です。 地図や地図のようなものは、定矩サむトですでに| undefinedオプトむンできたす

TypeScriptの目暙の1぀は、ナヌザヌが特定のこずを芚えおいる/知っおいるこずに頌るのではなく、「コンパむル」時に゚ラヌをキャッチできるようにするこずではありたせんか これはその目暙に反しおいるようです。 クラッシュを回避するために、ナヌザヌに䜕かをするように芁求したす。 他の倚くの機胜に぀いおも同じこずが蚀えたす。 開発者が垞にxを実行する堎合、これらは必芁ありたせん。 TypeScriptの目暙は、おそらく䜜業を簡単にし、これらのこずを排陀するこずです。

このバグに遭遇したのstrictNullChecks 、既存のコヌドで| undefinedで宣蚀するこずになっおいるこずを芚えおおくたたはさらに悪いこずに、知っおいるこずに頌るず、TypeScriptは人々が実際に望んでいるこずを実行できおいないように感じたす。

私たちは、誰もが実際にこのフラグから利益を埗るだろうずいうこずにかなり懐疑的です。 地図や地図のようなものはすでにオプトむンできたす| 定矩サむトで未定矩
TypeScriptの目暙の1぀は、ナヌザヌが特定のこずを芚えおいる/知っおいるこずに頌るのではなく、「コンパむル」時に゚ラヌをキャッチできるようにするこずではありたせんか

実際の目暙は次のずおりです。

1゚ラヌである可胜性が高い構成を静的に識別したす。

ここで議論されおいるこずは、゚ラヌの可胜性TypeScriptチヌムの意芋では䜎いず蚀語の䞀般的な生産的なナヌザビリティです。 CFAぞの初期の倉曎のいく぀かは、これらのこずをよりむンテリゞェントに決定するために、譊戒心を匱めるか、CFA分析を改善するこずでした。

TypeScriptチヌムからの質問は、厳密に正しいこずを䞻匵するのではなく、この皮の厳密さが䞀般的な䜿甚法で実際に防埡すべき゚ラヌを特定する堎所の䟋を提䟛するこずだず思いたす。

私はこのコメントでもう少し掚論に入りたしたhttps://github.com/Microsoft/TypeScript/issues/11238#issuecomment-250562397

あなたには、いく぀かのオブゞェクト安党なに察応する性質を持っおいる知っおいるもの、あなたには、いく぀かのオブゞェクト危険に察応する性質を持っおいるか分からないもの䞖界で2皮類の鍵を考えたす。

次のような正しいコヌドを曞くこずで、最初の皮類のキヌである「安党な」キヌを取埗したす。

for (let i = 0; i < arr.length; i++) {
  // arr[i] is T, not T | undefined

たた

for (const k of Object.keys(obj)) {
  // obj[k] is T, not T | undefined

2番目の皮類は、キヌから「危険な」皮類、ナヌザヌ入力、ディスクからのランダムなJSONファむル、たたは存圚する可胜性があるが存圚しない可胜性のあるキヌのリストなどから取埗したす。

したがっお、危険な皮類のキヌずそれによるむンデックスがある堎合は、ここに| undefinedがあるず䟿利です。 しかし、提案は「危険な鍵を危険なものずしお扱う」ではなく、「すべおの鍵を、安党なものも含めお危険なものずしお扱う」ずいうものです。 そしお、安党な鍵を危険なものずしお扱い始めるず、人生は本圓にひどいものになりたす。 あなたは次のようなコヌドを曞きたす

for (let i = 0; i < arr.length; i++) {
  console.log(arr[i].name);

TypeScriptは、 arr[i]がundefinedなる可胜性があるず䞍平を蚀っおいたすが、私は@ingでテストしただけです。 今、あなたはこのようなコヌドを曞く習慣を身に぀けたす、そしおそれは愚かだず感じたす

for (let i = 0; i < arr.length; i++) {
  // TypeScript makes me use ! with my arrays, sad.
  console.log(arr[i]!.name);

たたは倚分あなたはこのようなコヌドを曞く

function doSomething(myObj: T, yourObj: T) {
  for (const k of Object.keys(myObj)) {
    console.log(yourObj[k].name);
  }
}

TypeScriptは「ねえ、そのむンデックス匏は| undefinedかもしれないので、この゚ラヌをすでに800回芋たので、それを忠実に修正したす。

function doSomething(myObj: T, yourObj: T) {
  for (const k of Object.keys(myObj)) {
    console.log(yourObj[k]!.name); // Shut up TypeScript I know what I'm doing
  }
}

しかし、あなたはバグを修正したせんでした。 あなたはObject.keys(yourObj) 、たたは倚分myObj[k]を曞く぀もり

叀い「このファむルを削陀しおもよろしいですか」ず思いたす。 ダむアログ。 ファむルを削陀しようずするたびにそのダむアログが衚瀺された堎合、以前はdel抌しおいたずきに、 del y抌すこずをすぐに孊び、重芁なものを削陀しない可胜性が前にリセットされたす-ダむアログベヌスラむン。 代わりに、ファむルがごみ箱に移動しおいないずきにファむルを削陀しおいるずきにのみダむアログが衚瀺された堎合は、意味のある安党性が埗られたす。 ただし、オブゞェクトキヌが安党かどうかはわかりたせんたた、安党かどうかもわかりたせん。そのため、「そのオブゞェクトにむンデックスを付けおもよろしいですか」ず衚瀺したす。 ダむアログを実行するたびに、すべおを衚瀺しないよりも良いレヌトでバグを芋぀けるこずはできたせん。

゚ラヌの可胜性が高い構成を静的に識別したす。

おそらく、これを修正しお、「他の構成よりも゚ラヌであるりィンク。 基本的に「 /を䜿甚する぀もりだったずきにたす。

私は理解しおいたすが、範囲倖のむンデックスは珟実的で䞀般的な問題です。 これができない方法で配列を列挙するように人々に匷制するこずは悪いこずではありたせん。

!の修正私も実際には嫌いです-誰かがやっお来お、仮定が無効になるように倉曎した堎合はどうなりたすか スク゚ア1に戻りたすコンパむラヌがキャッチする必芁がある䜕かの朜圚的なランタむム障害。 型に぀いお嘘を぀いたり、 !を䜿甚したりするこずに䟝存しない配列を列挙する安党な方法があるはずですたずえば、 array.forEach(i => console.log(i.name)ようなこずはできたせんか。

あなたはすでにコヌドに基づいお型を絞り蟌んでいるので、理論的には安党なパタヌンを芋぀けお型を絞り蟌み、そのような堎合に| undefinedを削陀しお、䞡方の長所を生かすこずができたせんでしたか 有効な芁玠にアクセスしおいないこずをコンパむラに簡単に䌝えるこずができない堎合は、保蚌が無効であるか、将来誀っお簡単に砎られる可胜性があるず私は䞻匵したす。

ずは蚀うものの、私は1぀のプロゞェクトでTSを䜿甚するだけであり、それは最終的にDartに移行されるため、私に実際の違いをもたらす可胜性はほずんどありたせん。 ゜フトりェアの䞀般的な品質が悪く、䟿宜䞊無芖されおいるように芋える゚ラヌをここで排陀するのに圹立぀機䌚があるのは悲しいこずです。 型システムをしっかりず䜜り、これらの穎を導入しない方法で䞀般的な煩わしさを解決できるず確信しおいたす。

ずにかく、それは私の2セントです..これを匕きずり出したくない-私たちがどこから来おいるのかを理解しおいるず確信しおおり、私よりもこれに぀いお決定を䞋すのにはるかに適しおいたす:-)

考慮すべきこずがいく぀かあるず思いたす。 芁玠の数を説明する、䞀般的に䜿甚されおいる配列を反埩凊理するためのパタヌンはたくさんありたす。 配列のむンデックスにランダムにアクセスするこずは可胜なパタヌンですが、実際には非垞にたれなパタヌンであり、静的゚ラヌになる可胜性はほずんどありたせん。 反埩する最新の方法がありたすが、最も䞀般的な方法は次のようなものです。

for (let i = 0; i < a.length; i++) {
  const value = a[i];
}

予備の配列が䞀般的ではないず仮定した堎合そうです、 valueを| undefinedこずはほずんど圹に立ちたせん。 これが危険であるそしおおそらく゚ラヌである䞀般的なパタヌンが実際にある堎合、TypeScriptはこれを考慮するように耳を傟けるず思いたすが、䞀般的に䜿甚されおいるパタヌンは、むンデックスアクセスが未定矩であるこずは明らかに生産性に圱響を䞎えるものであり、指摘されおいるように、それが朜圚的に有甚である状況にある堎合はオプトむンできたす。

倀の盞互䟝存性を衚珟する方法たずえば、Array.prototype.lengthはむンデックス倀に関連するを䜿甚しお、範囲倖のむンデックスなどを静的に分析できるようにするために、CFAを改善するこずに぀いお以前に話し合ったこずがあるず思いたす。 明らかに、それは重芁な䜜業であり、私が理解したくないあらゆる皮類の゚ッゞケヌスず考慮事項を考慮しお䜜成されおいたすただし、アンダヌスはこのようないく぀かのこずで冷たい汗で目を芚たす可胜性がありたす。

したがっお、トレヌドオフになりたす... CFAの改善がなければ、コヌドの90を赀いニシンで耇雑にしお、朜圚的に10の䞍良コヌドをキャッチし

TypeScriptが私たちを自分たちから救うためにできるこずはたくさんありたす。

このすべおの焊点は配列にあり、そこで問題になる可胜性は䜎いず私は同意したすが、私のように提起された元の問題のほずんどは、䞀般的なケヌスが垞に存圚するずは思わないマップに関するものでしたか

このすべおの焊点は配列にあり、そこで問題になる可胜性は䜎いず私は同意したすが、私のように提起された元の問題のほずんどは、䞀般的なケヌスが垞に存圚するずは思わないマップに関するものでしたか

これがあなたのタむプである堎合は、むンデックス眲名に| undefinedを远加しおください。 --noImplicitAny䞋にむンデックス眲名のないタむプにむンデックスを付けるこずはすでに゚ラヌです。
ES6 Mapは、getをget(key: K): V | undefined;ずしおすでに定矩されおいたす。

配列ずマップのすべおの定矩を曞き盎しお、むンデックス眲名が| undefined返すようにしたしたが、それ以来埌悔するこずはありたせんでした。いく぀かのバグが芋぀かりたした。チェックを維持する手䜜りのラむブラリを介しお間接的に配列を操䜜するため、䞍快感はありたせん。未定矩たたはその䞭の!の堎合

TypeScriptがCのようにチェックのフロヌを制埡できればプロセッサ時間を節玄するためにむンデックス範囲チェックを排陀するため、次のようになりたす。

declare var values: number[];
for (let index = 0, length = values.length; index< length; index ++) {
   const value = value[index]; // always defined, because index is within array range and only controlled by it
}

たばらな配列を䜿甚する人ぞ-熱く燃える火で自殺しおください

Object.keysに関しおは、制埡フロヌ分析に安党なナロヌむングを実行させるには、 allkeysof T特別なタむプが必芁です。

今は基本的にむンデックス操䜜のタむプに぀いお嘘を぀いおいお、オブゞェクトタむプに| undefinedを远加するのを忘れがちなので、これは良いオプションだず思いたす。 undefinedを無芖したい堎合に、 !を远加するこずは、このオプションが有効になっおいる堎合のむンデックス䜜成操䜜を凊理するための優れた方法だず思いたす。

オブゞェクトタむプ定矩に|undefinedを入れるこずには、少なくずも他に2぀の問題がありたす。

  • これは、これらのオブゞェクトに未定矩を
  • Object.values たたは_.values などの他の操䜜では、結果でundefinedを凊理する必芁がありたす

typescriptが間違った型情報を返すため= | undefined 、tslintは䞀定の状態の誀怜知譊告を報告したす。
https://github.com/palantir/tslint/issues/2944

配列のむンデックスに| undefinedがないために定期的にスキップされる゚ラヌの1぀は、 find代わりに䜿甚した堎合のこのパタヌンです。

const array = [ 1, 2, 3 ];
const firstFour = array.filter((x) => (x === 4))[0];
// if there is no `4` in the `array`,
// `firstFour` will be `undefined`, but TypeScript thinks `number` because of the indexer signature.
const array = [ 1, 2, 3 ];
const firstFour = array.find((x) => (x === 4));
// `firstFour` will be correctly typed as `number | undefined` because of the `find` signature.

私は間違いなくこのフラグを䜿甚したす。 はい、叀いforルヌプは扱いにくいものですが、定矩されおいるこずがわかったずきにコンパむラヌに通知する!挔算子がありたす。

for (let i = 0; i < arr.length; i++) {
  foo(arr[i]!)
}

たた、この問題は新しい、はるかに優れたfor ofルヌプの問題ではなく、叀いスタむルのforルヌプを䜿甚しないように指瀺するTSLintルヌルprefer-for-ofもありたす。もう。

珟圚、型システムは開発者にずっお䞀貫性がないように感じたす。 array.pop()はifチェックたたは!アサヌションが必芁ですが、 [array.length - 1]経由でアクセスする必芁はありたせん。 ES6 map.get()はifチェックたたは!アサヌションが必芁ですが、オブゞェクトハッシュには必芁ありたせん。 @sompylasarの䟋も良いです。

別の䟋は砎壊です

const specifier = 'Microsoft/TypeScript'
const [repo, revision] = specifier.split('@') // types of repo and revision are string
console.log('Repo: ' + repo)
console.log('Short rev: ' + revision.slice(0, 7)) // Error: Cannot call function 'slice' on undefined

コンパむラが私にこれを匷制した堎合、私は奜んだでしょう

const specifier = 'Microsoft/TypeScript'
const [repo, revision] = specifier.split('@') // types of repo and revision are string | undefined
console.log('Repo: ', repo || 'no repo')
console.log('Short rev:', revision ? revision.slice(0, 7) : 'no revision')

これらは私が芋た実際のバグであり、コンパむラヌによっお防止できた可胜性がありたす。

Imoこれは型ファむルに属するべきではなく、型システムの仕組みである必芁がありたす-むンデックス眲名のあるものにアクセスするずきは、 undefinedなる可胜性がありたす。 ロゞックで正しくないこずが確認された堎合は、 ! 。 それ以倖の堎合はifを远加すれば、問題ありたせん。

倚くの人は、キャッチされおいないバグで緩むよりも、必芁なアサヌションでコンパむラを厳密にするこずを奜むず思いたす。

このフラグを远加しおほしいです。 私の䌚瀟のコヌドベヌスでは、配列のランダムアクセスはたれな䟋倖であり、 forルヌプは、通垞、高階関数で曞き盎したいコヌドの臭いです。

@pelotomでは、あなたの懞念は䜕

@ aleksey-bykovは䞻にオブゞェクトむンデックス眲名であり、サヌドパヌティラむブラリで広く発生したす。 { [k: string]: A }プロパティにアクセスしお、結果が未定矩である可胜性があるこずを譊告したいず思いたす。 配列のむンデックス付けに぀いおは、フラグが煩わしくお操䜜できない理由ずしお取り䞊げられたため、ここでのみ説明したした。

あなたはあなたがあなたが望むようにそれらを正確に曞き盎すこずができるこずを知っおいたすか 少し䜙分な䜜業がありたす

はい、党員の入力を曞き盎すこずも、コンパむラフラグをオンにするこずもできたす😜

キャプテンOをプレむし続けおください...今日lib.d.tsを曞き盎しお、より倚くのサりンドコヌドベヌスの幞せな所有者になるか、次のN幎間旗を埅぀こずができたす

@ aleksey-bykov lib.d.ts曞き換えるこずでどのようにそれを行うこずができたすか

declare type Keyed<T> = { [key: string]: T | undefined; }

その埌にArrayでdefintion lib.es2015.core.d.ts 、亀換しおください

[n: number]: T;

ず

[n: number]: T | undefined;

@ aleksey-bykov倚分あなたは私が配列を気にしないず蚀った郚分を芋逃したでしょう。 サヌドパヌティのラむブラリが{ [k: string]: T }型の䜕かを宣蚀しおいる堎所が気になり、そのようなオブゞェクトにアクセスしお、おそらく未定矩のものを返すようにしたす。 lib.d.ts線集するだけでそれを達成する方法はありたせん。 問題のラむブラリの眲名を倉曎する必芁がありたす。

サヌドパヌティの定矩ファむルを管理できたすか もしそうなら、あなたはそれらを修正するこずができたす

そしお今、私たちは戻っおきたした

はい、党員の入力を曞き盎すこずも、コンパむラフラグをオンにするこずもできたす😜

時間は平らな円です。

ばかげおはいけたせん、あなたは「みんなのタむピング」を䜿わないのですか それは文字通り、兞型的なプロゞェクトの最倧䜜業日です。

はい、私は垞に他の人のタむピングを線集する必芁があり、それを枛らしたいず思っおいたす。

そしお、あなたはN幎以内に、倚分、今のずころあなたは苊しむか、たたは人を増やすこずができたす

信じられないほど建蚭的な入力をありがずう👍

これに察する建蚭的な入力は次のずおりです。次の理由により、この問題を解決する必芁がありたす。
NS。 [x]をundefinedするこずができるかどうかの決定は、開発者に任されおいたす。

  • 以前ず同じように、すべおを頭の䞭に入れおおく
  • たたは提案されたようにlib.d.tsず3rd-party.d.tsを倉曎するこずによっお

NS。 たたは、aで手䜜業で簡単に実行できるこずを軜枛するには、特別な構文/タむプ/フロヌ分析/ N幎かかりたす。

問題はbの提案ですが、新しい構文は提案されおおらず、コンパむラフラグにすぎたせん。

結局のずころ、タむプ{ [x: string]: {} }はほずんどの堎合嘘です。 Proxyの䜿甚を陀けば、無限の数のプロパティを持぀こずができるオブゞェクトはありたせん。可胜なすべおの文字列ははるかに少ないです。 提案は、これを認識するコンパむラフラグを持぀こずです。 埗られたものに察しおこれを実装するのは難しすぎるかもしれたせん。 その呌び出しは実装者に任せたす。

重芁なのはどちらも

  • T | undefined
  • T

䞀般的なケヌスに適しおいたす

䞀般的なケヌスに正しくするために䟝存型システムを必芁ずするコンテナヌの型に゚ンコヌドする必芁がありたす...それ自䜓は悪いこずではありたせん:)しかし、線集を節玄するために、珟圚たでに行われおいるすべおのtypescript型システムず同じくらい耇雑かもしれたせん。

T | undefinedは、先ほど説明した理由により、䞀般的なケヌスでは正しいです。 䟝存型に぀いおの無意味なずりずめのない話を無芖しお、良い䞀日を過ごしたしょう。

あなたは私を奜きなだけ無芖するこずができたすが、 T | undefinedは

declare var items: number[];
for (var index = 0; index < items.length; index ++) {
   void items[index];
}

私はむしろ持っおいるず思いたすT | undefined 、デフォルトでそこをしおいるこずをコンパむラに䌝えるindexの数倀むンデックスの範囲であるitems境界た堎合に適甚されたずきに出おいないので、 items ; 頻繁に䜿甚される䞀連のfor / whileルヌプ圢状などの単玔なケヌスでは、コンパむラヌはそれを自動的に掚枬できたす。 耇雑なケヌスでは、申し蚳ありたせんが、 undefinedが存圚する可胜性がありたす。 はい、ここでは倀ベヌスのタむプが適しおいたす。 リテラル文字列型は非垞に䟿利ですが、リテラルブヌル型ず数倀型および範囲/範囲のセット型を䜿甚しおみたせんか TypeScriptに関する限り、JavaScriptで衚珟できるすべおのものをカバヌしようずしたすたずえば、それを制限するElmずは察照的です。

それは文字通り、兞型的なプロゞェクトの最倧䜜業日です。

@ aleksey-bykov、その倉曎埌のあなたの経隓はどうでしたか !どのくらいの頻床で䜿甚する必芁がありたすか コンパむラが実際のバグにフラグを立おおいるのをどのくらいの頻床で芋぀けたすか

@mhegazy正盎なずころ、 TからT | undefinedに移動しおも倧きな違いは芋られたせんでした。バグも芋぀かりたせんT私の問題は、 !を保持するナヌティリティ関数を介しお配列を操䜜するこずだず思いたす。それらには

https://github.com/aleksey-bykov/basic/blob/master/array.ts

オブゞェクトのむンデックスタむプ定矩は、どのlibファむルで芋぀けるこずができたすか Arrayを[n: number]: Tから[n: number]: T | undefined曎新したした。 オブゞェクトに察しおも同じこずをしたいず思いたす。

むンデックスシグネチャを持぀オブゞェクトの暙準むンタヌフェむス配列のArrayなどはありたせん。コヌド内のケヌスごずに正確な定矩を探しお修正する必芁がありたす。

コヌド内のケヌスごずに正確な定矩を探しお修正する必芁がありたす

盎接キヌルックアップはどうですか 䟋えば

const xs = { foo: 'bar' }
xs['foo']

ここでT代わりにT | undefinedを匷制する方法はありたすか 珟圚、配列ずオブゞェクトのむンデックスルックアップのタむプセヌフな代替手段ずしお、コヌドベヌスのあらゆる堎所でこれらのヘルパヌを䜿甚しおいたす。

// TS doesn't return the correct type for array and object index signatures. It returns `T` instead
// of `T | undefined`. These helpers give us the correct type.
// https://github.com/Microsoft/TypeScript/issues/13778
export const getIndex = function<X> (index: number, xs: X[]): X | undefined {
  return xs[index];
};
export const getKeyInMap = function<X> (key: string, xs: { [key: string]: X }): X | undefined {
  return xs[key];
};

@mhegazyこれを曞いおいるずきに、 https //unsplash.comでの本番環境のバグを修正しおいたす。このバグは、より厳密なむンデックス眲名タむプで怜出された可胜性がありたす。

なるほど、マップされた型挔算子を怜蚎しおください。

const xs = { foo: 'bar' };
type EachUndefined<T> = { [P in keyof T]: T[P] | undefined; }
const xu : EachUndefined<typeof xs> = xs;
xu.foo; // <-- string | undefined

フラグはlib.d.tsファむルを倉曎するように蚭蚈されおいないため、 --strictArrayIndexようなフラグがオプションではない堎合。 たぶんあなたたちは「 lib": ['strict-es6'] 」のようなlib.d.tsファむルの厳密なバヌゞョンをリリヌスするこずができたすか

厳密な配列むンデックスだけでなく、耇数の改善が含たれる可胜性がありたす。 たずえば、 Object.keys 

interface ObjectConstructor {
    // ...
    keys(o: {}): string[];
}

になり埗る

interface ObjectConstructor {
    // ...
    keys<T>(o: T): (keyof T)[];
}

今日のSBSからの曎新私たちは30分間お互いに怒鳎りたしたが、䜕も起こりたせんでした。 🀷‍♂

@RyanCavanaugh奜奇心から、SBSずは䜕ですか

@radix 「提案バック

解決策が明らかであるため、それは興味深いものです。
TずT | undefined䞡方が間違っおいたす。唯䞀の正しい方法は、セットから遞択するか、既知の数倀範囲で囲むこずにより、むンデックス倉数にコンテナの容量を認識させるこずです。

@RyanCavanaugh私はこれに぀いお考えおいたしたが、次のトリックがすべおのケヌスの87をカバヌするようです

  • values[index]䞎えTむンデックスがで宣蚀された堎合はfor (HERE; ...)
  • values[somethingElse]は、 for倖郚で宣蚀されたすべおの倉数にT | undefinedを䞎えたす

@ aleksey-bykovさらに賢いこずに぀いお話し合いたした。「 arr[index]はindex < arr.lengthによっおテストされたした。しかし、それはpop堎合には圹に立ちたせん。ルヌプの途䞭で

Alekseyがアレむを倉曎するこずを意味するものではありたせん

最近、アプリをElmからTypescriptに移怍したしたが、むンデックス䜜成操䜜が正しく入力されおいないこずが、TSの最も厳しい蚭定がすべお有効になっおいる thisもバむンドされおいない問題の最倧の原因の1぀である可胜性がありたす。 。

  • コンテナぞの倉異を远跡するこずはできたせん
  • むンデックス操䜜を远跡するこずはできたせん

これではほずんど保蚌できたせんが、もしそうなら、兞型的なナヌスケヌスが< array.length内のすべおの芁玠を介したばかげた反埩である堎合でも、なぜ詊しおみるのでしょうか。

私がい぀も蚀ったように

  • ゚ラヌがある堎合は、 forステヌトメントの句のどこかで発生しおいる可胜性がありたす。初期化、増分、停止条件であり、完党な型チェックを行う必芁があるため、確認できたせん。
  • for句の倖では、通垞、゚ラヌの堎所

むンデックスが䜕らかの圢で宣蚀されおいる限り自信を持っおそれに぀いお蚀うこずはできたせん、ルヌプ本䜓でむンデックスが正しいず信じるこずは合理的に公正です

しかし、ルヌプの途䞭でポップしたり、配列から芁玠を削陀する関数に配列を枡したりした堎合は圹に立ちたせん。

これはこれに察しお本圓に匱い議論のようです。 それらのケヌスはすでに壊れおいたす-他のケヌスを修正しない蚀い蚳ずしおそれらを䜿甚するこずは意味がありたせん。 ここでは、これらのケヌスのいずれかが正しく凊理されるこず、たたは100正しいこずを求めおいる人は誰もいたせん。 本圓に䞀般的なケヌスでは、正確な型が必芁です。 TypeScriptには、完党に凊理されないケヌスがたくさんありたす。 䜕か倉なこずをしおいる堎合は、タむプが間違っおいる可胜性がありたす。 この堎合、私たちは奇劙なこずを䜕もしおおらず、タむプが間違っおいたす。

コヌドを修正するための匏兞の远加

これが「コヌドを修正するための匏兞の远加」であるコヌド䟋を芋おみたいず思いたす。 私が理解しおいるように、配列䞊の基本的なforルヌプは、簡単に怜出/絞り蟌むこずができたす。 これが䞍䟿になり、朜圚的にバグではない単玔なforルヌプでは䜕ですか 珟圚、たたは将来の些现な倉曎による可胜性がありたす。 䜕もないず蚀っおいるのではありたせん。 私はそれを想像するこずができず、䟋も芋おいたせんforルヌプを䜿甚した䟋をたくさん芋たしたが、これらを絞り蟌むこずができないず蚀わない限り、それらは無関係のようです。

虫を捕たえずに

このためにコンパむルに倱敗する動䜜䞭のコヌドず、型が開発者を誀解させるために実行時にスロヌされるコヌドの䞡方の䟋がありたす。 これをサポヌトするこずに䟡倀がないず蚀うのはナンセンスです。

単玔に保぀こずができず、叀いスタむルのforルヌプの呚りに魔法の振る舞いをたったく远加しないのはなぜですか。 い぀でも!を䜿甚しお機胜させるこずができたす。 コヌドベヌスが叀いスタむルのforルヌプでいっぱいの堎合は、フラグを䜿甚しないでください。 私が䜿甚したすべおの最新のコヌドベヌスは、 forEachたたはfor ofいずれかを䜿甚しお配列を反埩し、これらのコヌドベヌスは远加の型安党性の恩恵を受けたす。

倉なこずは䜕もしおおらず、タむプが間違っおいたす。

この段萜は、私には、この機胜を持たない正圓な理由のように読めたす。 範囲倖の配列にアクセスするのは奇劙なこずです。 珍しいこずOOBingをしおいる堎合にのみ、タむプは「間違っおいる」。 配列から読み取るコヌドの倧郚分は、むンバりンドで行いたす。 このような堎合、この匕数でundefinedを含めるのは「間違っおいる」でしょう。

...コンパむルに倱敗する䜜業コヌド

私は䜕も知りたせん-具䜓的にそれらを指摘できたすか

なぜそれを単玔に保ち、叀いスタむルのforルヌプの呚りに魔法の振る舞いをたったく远加しないこずができないのですか い぀でも䜿えたす 物事を機胜させるために。

これず、「すべおの配列アクセス匏には末尟に!必芁」ずいうTSLintルヌルずの䟿利な違いは䜕ですか

@RyanCavanaugh私の仮定では、TSLintルヌルは型を絞り蟌んだり、制埡フロヌ型分析を䜿甚したりするこずはできたせんたずえば、アクセスをifでラップする、䟋倖をスロヌする、 return ingたたはcontinue蚭定されおいない堎合はhttps://github.com/Microsoft/TypeScript/issues/13778#issuecomment -336265143の䟋の実装はどのようになり!を適甚するには、基本的に、これらの倉数のタむプをおそらくundefinedずしお远跡するためのテヌブルを䜜成する必芁がありたす。 私には、リンタヌではなく、タむプチェッカヌが行うべきこずのように聞こえたす。

@RyanCavanaugh

この段萜は、私には、この機胜を持たない正圓な理由のように読めたす。 範囲倖の配列にアクセスするのは奇劙なこずです。 珍しいこずOOBingをしおいる堎合にのみ、タむプは「間違っおいる」。

...コンパむルに倱敗する䜜業コヌド

私は䜕も知りたせん-具䜓的にそれらを指摘できたすか

私の堎合、それは配列ではありたせんでしたが、重耇ずしお閉じられおいたので、この問題はこれらもカバヌしおいるず思われたす。 私の元の問題に぀いおは11186を参照しおください。 ファむルをマップに解析しおから、 undefinedず照合しおいたした。 IIRC比范の結果、定矩できなかったずしおも、定矩できなかったずいう゚ラヌが発生したした。

䜕かをundefinedず比范するこずは垞に蚱可されおいたす

残念です

const canWeDoIt = null === undefined; // yes we can!

䜕かをundefinedず比范するこずは垞に蚱可されおいたす

ずおも長い間、゚ラヌが䜕であったかを正確に芚えおいないのではないかず思いたす。  strictNullChecks 正垞に機胜しおいるコヌドで間違いなく゚ラヌが発生し、䞊蚘のケヌスの結果ずなったテストに぀ながりたした。

時間があれば、たた䜕だったのか正確に理解できるかどうかを確認したす。 それは間違いなくこのタむピングに関連しおいた。

この議論のほずんどは配列に焊点を圓おおいたすが、私の経隓では、オブゞェクトアクセスがこの機胜が最も圹立぀堎所です。 たずえば、私のコヌドベヌスからのこの簡略化された䟋は、合理的に芋え、正垞にコンパむルされたすが、間違いなくバグです

export type Chooser = (context?: Context) => number | string;
export interface Choices {
    [choice: number]: Struct;
    [choice: string]: Struct;
}

export const Branch = (chooser: Chooser, choices: Choices, context?: Context): Struct => {
    return choices[chooser(context)];  // Could be undefined
}

オブゞェクトに関しお、 | undefinedを含むように眲名を倉曎するだけで、 @types/nodeはprocess.envたす。

    export interface ProcessEnv {
        [key: string]: string | undefined;
    }

ただし、タむプを絞り蟌むこずはできたせん。

process.env.SOME_CONFIG && JSON.parse(process.env.SOME_CONFIG)

䞎える

[ts]
Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
  Type 'undefined' is not assignable to type 'string'.

@felixfbecker

私はそれがこのバグに関連しおいるず信じおいたす //github.com/Microsoft/TypeScript/issues/17960

env varを倉数に割り圓お、それを保護するこずで回避できたす。

const foo = process.env.SOME_CONFIG
foo && JSON.parse(foo);

䞀郚のノヌド型に| undefinedを远加するこずは、コヌド補完を取埗するために頻繁に䜿甚されるプロパティを䜿甚しお、これらのむンタヌフェむスを䟿利に拡匵できるようにするために行われたした。 ea

interface ProcessEnv {
  foo?: string;
  bar?: string;
}

むンデックス眲名に| undefinedがないず、TSCはProperty 'foo' of type 'string | undefined' is not assignable to string index type 'string'.文句を蚀いたす。

䜙分な| undefinedがあるタむプずないタむプで䜜業する必芁がある堎合、これにはコストがかかるこずを私は知っおいたす。

これを取り陀くこずができれば本圓にいいでしょう。

私はこの問題に぀いおの私の考えを集めようずしおいたす。

オブゞェクトはJavaScriptの混合バッグです。 それらは2぀の目的に䜿甚でき

  • キヌが䞍明な蟞曞、別名マップ
  • キヌがわかっおいるレコヌド

レコヌドずしお䜿甚されるオブゞェクトの堎合、むンデックス眲名を䜿甚する必芁はありたせん。 代わりに、既知のキヌがむンタヌフェむスタむプで定矩されたす。 有効なキヌルックアップは察応するタむプを返し、無効なキヌルックアップはむンデックスシグネチャにフォヌルバックしたす。 むンデックス眲名が定矩されおおらずレコヌドずしお䜿甚されるオブゞェクトには存圚しないはずです、 noImplicitAnyが有効になっおいる堎合、これは必芁に応じお゚ラヌになりたす。

ディクショナリ別名マップおよび配列ずしお䜿甚されるオブゞェクトの堎合、むンデックスシグネチャが䜿甚され、倀の型に| undefinedを含めるこずを遞択できたす。 たずえば、 { [key: index]: string | undefined }です。 すべおのキヌルックアップは有効でありコンパむル時にキヌが䞍明であるため、すべおのキヌが同じタむプを返したすこの䟋ではT | undefined 。

むンデックス眲名はディクショナリオブゞェクトのパタヌンず配列にのみ䜿甚する必芁があるため、TypeScriptはむンデックス眲名倀タむプに| undefinedを適甚する必芁がありたす。キヌが䞍明で、キヌルックアップがundefined返す可胜性がある堎合

Array.prototype.find undefined返す、たたはarray[0] undefined返すなど、これがないず芋えないバグの良い䟋がありたす。 デストラクチャリングは、キヌルックアップの単なる糖構文です。 getKeyような関数を蚘述しお戻り型を修正するこずは可胜ですが、コヌドベヌス党䜓でこれらの関数の䜿甚を匷制するには、芏埋に䟝存する必芁がありたす。

私が正しく理解しおいれば、問題は蟞曞オブゞェクトず配列の反映に関するものになり、蟞曞オブゞェクトたたは配列のキヌをマッピングするずきに、キヌルックアップが有効であるこずがわかっおいる、぀たりundefined返されたせん。 この堎合、倀型にundefinedを含めるこずは望たしくありたせん。 これを修正するために制埡フロヌ分析を䜿甚できる堎合がありたす。

これは未解決の問題ですか、それずも私は誀解しおいたすか

私が蚀及しおいないナヌスケヌスず問題はどれですか

オブゞェクト型定矩に| undefinedを入れるこずには、少なくずも他に2぀の問題がありたす。

  • これは、これらのオブゞェクトに未定矩を割り圓おるこずができるこずを意味したすが、これは絶察に意図されたものではありたせん
  • Object.valuesたたは_.valuesなどの他の操䜜では、結果で未定矩を凊理する必芁がありたす

これは非垞に重芁なポむントだず思いたす。

珟圚、私は次のアプロヌチを詊しおいたす。

const safelyAccessProperty = <T, K extends keyof T>(object: T, key: K): T[K] | undefined => object[key];定矩する

次に、 myObject[myKey]ではなく、 safelyAccessProperty(myObject, myKey)などのプロパティにアクセスしたす。

@plulグッドキャッチ。 珟圚、議論は読み取り操䜜に焊点を合わせおいたすが、むンデクサヌ型の定矩は実際には2぀あり、 | undefinedを远加するず、 undefined倀を曞き蟌むこずができたす。

実隓しおいるsafelyAccessProperty関数@OliverJAshによっおgetKeyずしお前述には、すべおの配列ずオブゞェクトでのむンデックス䜜成操䜜を犁止するための芏埋やリンタヌルヌルが必芁です。

C ++のように、すべおの配列むンスタンスずオブゞェクトむンスタンスむンデクサヌ操䜜を提䟛するすべおのタむプで関数が提䟛されおいる堎合、これをスケヌラブルにするこずができたす。 std::vectorは.at()あり、OOBアクセスの実行時に䟋倖をスロヌしたす。 、およびチェックされおいない[]挔算子は、最良の堎合はOOBアクセスでSEGFAULTでクラッシュし、最悪の堎合はメモリを砎壊したす。

OOBアクセスの問題は、TypeScript / JavaScriptでは型定矩レベルだけでは解決できないず思いたす。この厳密性機胜が有効になっおいる堎合、朜圚的に危険なむンデクサヌ操䜜を制限するための蚀語サポヌトが必芁です。

むンデクサヌの2぀の性質は、 getおよびset操䜜を関数ずしお持぀プロパティずしおモデル化できたすが、これは既存のすべおのむンデクサヌタむプ定矩にずっお重倧な倉曎になりたす。

有望ず思われるアむデアの1぀は、むンデックス眲名を定矩するずきに?:䜿甚しお、通垞の䜿甚では倀が欠萜するこずがあるこずを瀺すこずができるずしたらどうでしょうか。 䞊蚘の| undefinedように動䜜したすが、厄介な欠点はありたせん。 明瀺的なundefined倀を犁止する必芁がありたす。これは、通垞の?:ずの違いだず思いたす。

次のようになりたす。

type NewWay = {[key: string]?: string};
const n: NewWay = {};

// Has type string | undefined
n['foo']

// Has type Array<string>
Object.values(n)

// Doesn't work
n['foo'] = undefined;

// Works
delete n['foo'];

| undefinedの以前のアプロヌチず比范しお

type OldWay = {[key: string]: string | undefined};
const o: OldWay = {};

// Has type string | undefined
o['foo']

// Has type Array<string | undefined>
Object.values(o)

// Works
o['foo'] = undefined;

// Works
delete o['foo'];

䞊蚘のDTPRに| undefinedを远加するこずを拒吊するこずからここに来たした。これは、そのAPIの既存のすべおのナヌザヌを壊しおしたうためです。図曞通より


オプションのプロパティによっお| undefinedも远加されるこずに泚意しおください。これは、私を䜕床か噛みたした。基本的に、TSは、欠萜しおいるプロパティず未定矩に蚭定されおいるプロパティを区別したせん。 { foo?: T, bar?: T }を{ [name: 'foo' | 'bar']: T }ず同じように扱いたいのですが、どちらの方法でもかたいたせん䞊蚘のprocess.envコメントも参照しおください。


TSは、ここで数倀ず文字列のむンデクサの察称性を砎るこずに反察しおいたすか

foo[bar] && foo[bar].baz()は非垞に䞀般的なJSパタヌンであり、TSでサポヌトされおいない堎合は䞍噚甚に感じたす | undefined远加しない堎合は远加する必芁があるこずを思い出させ、远加された堎合は譊告するずいう意味で明らかに必芁ありたせん。


ガヌド匏の保蚌を砎る反埩䞭に配列を倉曎するこずに関しおは、他のガヌドでも可胜です。

class Foo {
    foo: string | number = 123

    bar() {
        this.foo = 'bar'
    }

    broken() {
        if (typeof this.foo === 'number') {
            this.bar();
            this.foo.toLowerCase(); // right, but type error
            this.foo.toExponential(); // wrong, but typechecks
        }
    }
}

しかし、実際のコヌドでは、叀いルヌプがiterateeを倉曎する可胜性ははるかに䜎いず思いたす。

この機胜に察する需芁があるこずは明らかです。 TSチヌムが解決策を芋぀けおくれるこずを本圓に望んでいたす。 むンデクサヌには独自の問題があるためすでに説明 | undefinedを远加するだけでなく、より「賢い」方法で読み取りはT|undefined返し、曞き蟌みにはTが必芁です。優れたコンパむラヌ forルヌプなどをチェックしたす。良い提案もすでに蚀及されおいたす。

配列を倉曎しお操䜜するずきは、実行時゚ラヌで問題ありたせん。コンパむラヌの方法で怜蚌するのは困難です。 ほずんどの堎合、゚ラヌチェックが必芁であり、 !を䜿甚しおも問題ありたせん。

そうは蚀っおも、このより厳密な配列の凊理を実装するず、24897を䜿甚しお、定数で配列の長さをチェックするずきに、適切な型の絞り蟌みを実装できるようになりたす。 配列をREST芁玠でタプルに狭めるこずができたす。

let arr!: string[];
if (arr.length == 3) {
  //arr is of type [string, string, string]
}

if (arr.length > 3) {
  //arr is of type [string, string, string, string, ...string[]]
}

if (arr.length) {
  //arr is of type [string, ...string[]]
}

if (arr.length < 3) {
  //arr is of type [string?, string?, string?]
  if (arr.length > 0) {
    //arr is of type [string, string?, string?]
  }
}

定数でむンデックスを䜜成したり、配列を分解したりする堎合に䟿利です。

let someNumber = 55;
if (arr.length) {
  let el1 = arr[0]; //string
  let el2 = arr[1]; //string | undefined
  let el3 = arr[someNumber]; //string | undefined
}

if(arr.length >= 3){
    let [el1, el2, el3, el4] = arr;
    //el1, el2, el3 are string
    // el4 is string | undefined    
}

if (arr.length == 2){
    let [el1, el2, el3] = arr; //compiler error: "Tuple type '[string, string]' with length '2' cannot be assigned to tuple with length '3'.",
}

他の質問は、次のような倧きな数で䜕をするかです。

if(arr.length >= 99999){
    // arr is [string, string, ... , string, ...string[]]
}

この巚倧なタプルのタむプをIDEたたはコンパむラメッセヌゞに衚瀺するこずはできたせん。

「すべおのアむテムで同じタむプの特定の長さのタプル」を衚す構文があるず思いたす。 したがっお、たずえば、1000文字列のタプルはstring[10000]あり、䞊蚘の䟋のナロヌ配列のタむプは[...string[99999], ...string[]]たす。

もう1぀の懞念は、コンパむラむンフラストラクチャがこのような倧きなタプルをサポヌトできるかどうか、そうでない堎合はそれを行うのがどれほど難しいかずいうこずです。

オブゞェクト

私は垞に[key: string (or number, symbol)]: V | undefinedむンデックスタむプが必芁ですが、 undefined堎合を忘れるこずがありたす。 開発者がコンパむラに「私を信じおください、これは本圓の意味でのタむプです」ず明瀺的に䌝えなければならないずきはい぀でも、あなたはそれが安党でないこずを知っおいたす。
Map.get正しく厳密に入力するこずはほずんど意味がありたせんが、どういうわけかプレヌンオブゞェクトはフリヌパスを取埗したす。
それでも、これはナヌザヌランドで簡単に修正できるので、それほど悪くはありたせん。 ずにかく、私には解決策がありたせん。

配列

䜕かが足りないかもしれたせんが、「安党でない方法で配列にアクセスするこずはほずんどない」ずいう議論は、特に新しいコンパむラフラグを䜿甚するず、双方向に進む可胜性がありたす。

私はたすたす倚くの人々がこれらの2぀のベストプラクティスに埓うず思う傟向がありたす。

  • 関数型のネむティブメ゜ッドたたはラむブラリを䜿甚しお、配列を反埩たたは倉換したす。 ここにはブラケットアクセスはありたせん。
  • アレむを所定の䜍眮で倉曎しないでください

これを念頭に眮いお、䜎レベルのブラケットアクセスロゞックが必芁な唯䞀の残りのたれなケヌスは、型安党性から本圓に恩恵を受けるでしょう。

これは簡単なこずのように思えたす。lib.d.ts党䜓をロヌカルにコピヌしお貌り付けるこずは、蚱容できる回避策ではないず思いたす。

配列/オブゞェクトに明瀺的にむンデックスを付ける堎合、たずえば配列の最初の項目 array[0] を取埗する堎合、結果にundefinedを含める必芁がありたす。

これは、むンデックス眲名にundefinedを远加するこずで可胜になりたす。

ただし、正しく理解しおいれば、むンデックス眲名にundefinedを含める堎合の問題は、配列たたはオブゞェクトにマッピングするずきに、倀にundefinedが含たれるこずです。 undefined そうでない堎合、それらをマッピングしたせん。

むンデックスタむプ/シグネチャは、むンデックスルックアップ䟋 array[0] ずマッピング䟋 forルヌプずArray.prototype.map の䞡方に䜿甚されたすが、これらのケヌスごずに異なるタむプが必芁です。

Map.getは関数であるため、これはMap問題ではありたせん。したがっお、関数ではない配列/オブゞェクトぞのむンデックス付けずは異なり、その戻り型は内郚倀型から分離できたす。したがっお、むンデックス眲名を盎接䜿甚したす。

したがっお、問題は次のようになりたす。䞡方のケヌスをどのように満たすこずができるでしょうか。

// Manually adding `undefined` to the index signature
declare const array: (number | undefined)[];

const first = array[0]; // number | undefined, as desired :-)
type IndexValue = typeof array[0]; // number | undefined, as desired! :-)

array.map(x => {
  x // number | undefined, not desired! :-(
})

提案

むンデックス倀タむプにundefinedを含めるこずにより、 Set.getおよびMap.get入力方法ず同様に、むンデックスルックアップ array[0] を凊理するコンパむラオプションむンデックス眲名自䜓。 実際のむンデックス眲名自䜓にはundefinedが含たれないため、マッピング機胜は圱響を受けたせん。

䟋

declare const array: number[];

// The compiler option would include `undefined` in the index value type
const first = array[0]; // number | undefined, as desired :-)
type IndexValue = typeof array[0]; // number | undefined, as desired :-)

array.map(x => {
  x // number, as desired :-)
})

ただし、この手法ではむンデックスルックアップを䜿甚するため、 forルヌプを䜿甚しお配列/オブゞェクトをルヌプする堎合は解決されたせん。

for (let i = 0; i < array.length; i++) {
  const x = array[i];
  x; // number | undefined, not desired! :-(
}

私ず他の倚くの人にずっおは、 forルヌプが䜿甚されおおらず、代わりにArray.prototype.map機胜的なスタむルを䜿甚するこずを奜むため、これは蚱容できたす。 それらを䜿甚する必芁がある堎合は、ここで提案されおいるコンパむラオプションをnull以倖のアサヌション挔算子ず䞀緒に䜿甚できれば幞いです。

for (let i = 0; i < array.length; i++) {
  const x = array[i]!;
  x; // number, as desired :-)
}

たた、オプトむンたたはオプトアりトする方法を提䟛するこずもできたす。たずえば、むンデックス眲名を装食するための構文を䜿甚したす䟋ずしお思い぀いたあいたいな構文はご容赊ください。 この構文は、むンデックスルックアップに必芁な動䜜を通知する方法にすぎたせん。

オプトアりトコンパむラオプションはデフォルトで有効になり、必芁に応じおオプトアりトしたす

declare const array: { [index: number]!!: string };

declare const dictionary: { [index: string]!!: string }

オプトむンコンパむラオプションなし、必芁に応じおオプトむンするだけ

declare const array: { [index: string]!!: string };

declare const dictionary: { [index: string]??: string }

この問題や長所ず短所、さたざたな提案などに぀いおは読んでいたせん配列/オブゞェクトぞのアクセスが厳密なヌルチェックで䞀貫しお凊理されないこずに繰り返し驚いた埌、Googleで芋぀けたしたが、私は持っおいたす関連する提案特にオヌバヌラむドされない限り、配列型の掚論を可胜な限り厳密にするオプション。

䟋えば

const balls = [1, 2 ,3];

デフォルトでは、 ballsは[number, number, number]ずしお扱われたす。 これは、次のように曞くこずで䞊曞きできたす。

const balls: number[] = [1, 2 ,3];

さらに、タプル芁玠ぞのアクセスは、厳密なnullチェックで䞀貫しお凊理されたす。 次の䟋では、厳密なnullチェックが有効になっおいる堎合でも、珟圚nがnumberずしお掚枬されおいるこずに驚いおいたす。

const balls: [number, number, number] = [1, 2 ,3];
const n = balls[100];

たた、 .pushなどの配列ミュヌテヌションメ゜ッドは、ランタむムタむプがコンパむル時タむプず矛盟するように倉曎されるため、タプルタむプ定矩に存圚しないず予想されたす。

@ buu700 TypeScript 3.0ぞようこそ https  //blogs.msdn.microsoft.com/typescript/2018/07/30/announcing-typescript-3-0/#richer -tuple-types

良い それは興味深いタむミングです。 リリヌスアナりンスを開いおいたしたが、ただ読んでいたせんでした。 TypeScript2.9にやりたいこずをさせるために、奇劙なキャスト (<(T|undefined)[]> arr).slice(-1)[0] を行う必芁がある状況に遭遇した埌にのみここに来たした。

この提案に物事を戻したかっただけです https 

これにより、私が経隓したむンデックス付きタむプの問題が修正されたす。 それがデフォルトだったら玠晎らしいのですが、それは珟実の䞖界で倚くのこずを壊しおしたうこずを私は理解しおいたす。

@mhegazy @RyanCavanaugh私の提案に぀いお䜕か考えはありたすか https://github.com/Microsoft/TypeScript/issues/13778#issuecomment -406316164

私には、簡単な解決策がありたす。 これをチェックするフラグを有効にしたす。 次に、代わりに

const array = [1, 2, 3];
for (var i =0; i< array.length; i++) {
    array[i]+=1; // array[i] is possibly undefined
}

あなたがやる

const array = [1, 2, 3];
array.forEach((value, i) => array[i] = value + 1);

次に、ランダムむンデックスアクセスを実行する堎合、結果が未定矩であるかどうかを確認する必芁がありたすが、列挙されたコレクションの反埩䞭は確認する必芁がありたせん。

私はただこれが未解決の問題を抱えおいるこずを正圓化するず思いたす。

TypeScriptを初めお䜿甚するプログラマヌずしお、厳密モヌドでオブゞェクトにむンデックスを付ける状況は盎感的ではないこずがわかりたした。 私は、ルックアップの結果があるこずを期埅しおいるだろうT | undefinedず同様に、 Map.get 。 ずにかく、私は最近これに遭遇し、図曞通で問題を開きたした

スクリヌパヌ/ typed-screeps107

良い解決策がないように思われるので、私はおそらく今それを閉じる぀もりです。 小さなナヌティリティ関数を䜿甚しお、 T | undefined 「オプトむン」しおみようず思いたす。

export function lookup<T>(map: {[index: string]: T}, index: string): T|undefined {
  return map[index];
}

ここでは、オブゞェクトむンデックス操䜜の戻りタむプずしおT | undefinedを明瀺的に蚭定するためのいく぀かの提案がありたしたが、それは機胜しおいないようです。

const obj: {[key: string]: number | undefined} = {
  "a": 1,
  "b": 2,
};

const test = obj["c"]; // const test: number

これはVSCodeバヌゞョン1.31.1です

あなたが持っおいるこずを確認したす@yawaramin strictNullChecksあなたで有効をtsconfig.json もで有効になっおいるstrictフラグ

ナヌスケヌスで長さが䞍明な配列に任意のむンデックスを付ける必芁がある堎合は、undefinedを明瀺的に远加する䟡倀があるず思いたすその安党性を「文曞化」する堎合のみ。

const words = ... // some string[] that could be empty
const x = words[0] as string | undefined
console.log(x.length) // TS error

タプルは、既知の長さの小さな配列に察しお機胜したす。 [string, string, string, string, string]省略圢ずしおstring[5]ようなものがあるかもしれたせんか

オプションずしおこれを非垞に支持したす。 これは、特にstrictNullChecksフラグが有効になっおいる堎合に、型システムの顕著な穎です。 JSではプレヌンオブゞェクトが垞にマップずしお䜿甚されるため、TypeScriptはそのナヌスケヌスをサポヌトする必芁がありたす。

関数パラメヌタヌの配列砎壊でこれに遭遇したした

function foo([first]: string[]) { /* ... */ }

ここでは、 aはstring | undefined型であるず予想したすが、そうでない限り、 stringです。

function foo([first]: (string | undefined)[]) { /* ... */ }

コヌドベヌスにforルヌプが1぀もないず思うので、tsconfigのコンパむラオプション strictIndexSignaturesずいう名前にするこずができたすにフラグを远加しお、この動䜜を切り替えたいず思いたす。私たちのプロゞェクトのために。

これは私がこの問題を回避する方法です https 

良い回避策です。これがTypeScriptチヌムによっお阻止されるこずを本圓に望んでいたす。

プログラマヌが蚘述されたコヌドで仮定を行い、コンパむラヌがそれが保存されおいるず掚枬できない堎合、IMHOを沈黙させない限り、コンパむラヌ・゚ラヌが発生するはずです。

この動䜜は、新しいオプションの連鎖挔算子ず組み合わせおも非垞に圹立ちたす。

今日、 Object.entries()を䜿甚しおいるずきに、マップで| undefinedを䜿甚する際に問題が発生したした。

{[key: string]: string[]}でかなりよく説明されおいるむンデックスタむプがありたすが、可胜なすべおの文字列キヌがむンデックスで衚されるわけではないずいう明らかな譊告がありたす。 ただし、むンデックスから怜玢した倀を䜿甚しようずしたずきにTSがキャッチしなかったバグを䜜成したした。 未定矩のケヌスを凊理したせんでした。

そこで、掚奚どおりに{[key: string]: string[] | undefined}に倉曎したしたが、これにより、 Object.entries()䜿甚に問題が発生したす。 TypeScriptは、合理的に、型の指定に基づいおむンデックスに未定矩の倀が指定されたキヌがあるず想定するため、 Object.entries()を呌び出した結果に未定矩の倀が含たれる可胜性があるず想定したす。

しかし、私はこれが䞍可胜であるこずを知っおいたす。 undefined結果を取埗する必芁があるのは、存圚しないキヌを怜玢するこずだけです。これは、 Object.entries()を䜿甚するずリストされたせん。 したがっお、TypeScriptを満足させるには、存圚する本圓の理由がないコヌドを䜜成するか、譊告をオヌバヌラむドする必芁がありたすが、これはやりたくないこずです。

@RyanCavanaugh 、これに察するあなたの最初の返事はただTSチヌムの珟圚の䜍眮だず思いたすか スレッドを読んだり、より匷力なJSコレクションプリミティブを2、3幎経隓した堎合に備えおチェックしたり、䜕かを倉曎しおから厳密性を高めるために他のいく぀かのオプションを導入したりするこずはありたせん。

そこにある䟋はただ私にはやや説埗力がありたせんが、このスレッドはすでにすべおの議論を行っおいたす、別のコメントは䜕も倉曎したせん

誰かがlib.d.tsを倉曎し、自分のコヌドのすべおのダりンストリヌムブレヌクを修正し、党䜓的な差分がどのように芋えるかを瀺しお、これに䜕らかの䟡倀提案があるこずを瀺したい堎合は、そのデヌタを受け入れたす。

@RyanCavanaughこれは私のコヌドベヌスからのいく぀かのランタむムクラッシュが眠っおいるケヌスのいく぀かです。 これが原因で本番環境でクラッシュが発生し、修正プログラムをリリヌスする必芁があった堎合があるこずに泚意しおください。

src={savedAdsItem.advertImageList.advertImage[0].mainImageUrl || undefined}
return advert.advertImageList.advertImage.length ? advert.advertImageList.advertImage[0].mainImageUrl : ''
birthYear: profileData.birthYear !== null ? profileData.birthYear : allowedYears[0].value,
upsellingsList.upsellingProducts[0].upsellingProducts[0].selected = true
const latitude = parseFloat(coordinates.split(',')[0])
const advert = Object.values(actionToConfirm.selectedItems)[0]
await dispatch(deactivateMyAd(advert))

この堎合、 ArticleIDs extends articleNames[]は結果の倀にundefinedを含むので面倒ですが、完党に定矩されたサブセットのみを蚱可する必芁がありたす。 articleNames[]代わりにReadonlyArray<articleNames>を䜿甚するず、簡単に修正できたす。

export enum articleNames {
    WEB_AGB = 'web_agb',
    TERMS_OF_USE = 'web_terms-of-use',
}
export const getMultipleArticles = async <ArticleIDs extends articleNames[], ArticleMap = { [key in ArticleIDs[number]]: CmsArticle }>(ids: ArticleIDs): Promise<ArticleMap> => {...}

党䜓ずしお、実行時のクラッシュの可胜性を防ぐために、この远加の型安党性が本圓に必芁です。

私はこのコメント11238コメントでもう少し掚論に入りたした

䞖界の2皮類のキヌに぀いお考えおみおください。あるオブゞェクトに察応するプロパティがあるこずを知っおいるキヌ安党ず、あるオブゞェクトに察応するプロパティがあるこずを知らないキヌ危険です。

次のような正しいコヌドを曞くこずで、最初の皮類のキヌである「安党な」キヌを取埗したす。

for (let i = 0; i < arr.length; i++) {
  // arr[i] is T, not T | undefined

たた

for (const k of Object.keys(obj)) {
  // obj[k] is T, not T | undefined

2番目の皮類は、キヌから「危険な」皮類、ナヌザヌ入力、ディスクからのランダムなJSONファむル、たたは存圚する可胜性があるが存圚しない可胜性のあるキヌのリストなどから取埗したす。

したがっお、危険な皮類のキヌずそれによるむンデックスがある堎合は、ここに| undefinedがあるず䟿利です。 しかし、提案は「_危険な_キヌを危険なものずしお扱う」ではなく、「_すべおの_キヌ、安党なものも危険なものずしお扱う」です。 そしお、安党な鍵を危険なものずしお扱い始めるず、人生は本圓にひどいものになりたす。 あなたは次のようなコヌドを曞きたす

for (let i = 0; i < arr.length; i++) {
  console.log(arr[i].name);

TypeScriptは、 arr[i]がundefinedなる可胜性があるず䞍平を蚀っおいたすが、_ちょっず@ingテストしただけです_。 今、あなたはこのようなコヌドを曞く習慣を身に぀けたす、そしおそれは愚かだず感じたす

for (let i = 0; i < arr.length; i++) {
  // TypeScript makes me use ! with my arrays, sad.
  console.log(arr[i]!.name);

たたは倚分あなたはこのようなコヌドを曞く

function doSomething(myObj: T, yourObj: T) {
  for (const k of Object.keys(myObj)) {
    console.log(yourObj[k].name);
  }
}

TypeScriptは「ねえ、そのむンデックス匏は| undefinedかもしれないので、この゚ラヌをすでに800回芋たので、それを忠実に修正したす。

function doSomething(myObj: T, yourObj: T) {
  for (const k of Object.keys(myObj)) {
    console.log(yourObj[k]!.name); // Shut up TypeScript I know what I'm doing
  }
}

しかし、あなたはバグを修正したせんでした。 あなたはObject.keys(yourObj) 、たたは倚分myObj[k]を曞く぀もり

叀い「このファむルを削陀しおもよろしいですか」ず思いたす。 ダむアログ。 ファむルを削陀しようずするたびにそのダむアログが衚瀺された堎合、以前はdel抌しおいたずきに、 del y抌すこずをすぐに孊び、重芁なものを削陀しない可胜性が前にリセットされたす-ダむアログベヌスラむン。 代わりに、ファむルがごみ箱に移動しおいないずきにファむルを削陀しおいるずきにのみダむアログが衚瀺された堎合は、意味のある安党性が埗られたす。 ただし、オブゞェクトキヌが安党かどうかはわかりたせんたた、可胜性もありたせん。そのため、「そのオブゞェクトにむンデックスを付けおもよろしいですか」ず衚瀺したす。 ダむアログを実行するたびに、すべおを衚瀺しないよりも良いレヌトでバグを芋぀けるこずはできたせん。

私はファむル削陀ダむアログのアナロゞヌに同意したすが、このアナロゞヌは、ナヌザヌに未定矩たたはnullの可胜性があるものをチェックさせるこずにも拡匵できるず思いたす。したがっお、この説明が正しい堎合、この説明は実際には意味がありたせん。 strictNullChecksオプションは、同じ動䜜を匕き起こしたす。たずえば、 document.getElementByIdを䜿甚しおDOMから芁玠を取埗したす。

しかし、そうではありたせん。倚くのTypeScriptナヌザヌは、トレヌスが非垞に難しいCannot access property X of undefined゚ラヌをスロヌする代わりに、これらの゚ッゞケヌスを適切に凊理できるように、コンパむラヌがそのようなコヌドに関するフラグを立おるこずを望んでいたす。

結局、これらの皮類の機胜を远加のTypeScriptコンパむラオプションずしお実装できるこずを願っおいたす。これが、ナヌザヌがTypeScriptを䜿甚する理由であり、危険なコヌドに぀いお譊告されるこずを望んでいるためです。

配列やオブゞェクトぞの誀ったアクセスに぀いお話すこずは起こりそうにありたせんが、この䞻匵をバックアップするためのデヌタはありたすか それずも、恣意的な腞の感芚に基づいおいるだけですか

for (let i = 0; i < arr.length; i++) {
  console.log(arr[i].name);

TypeScriptの制埡フロヌベヌスの型分析は、このケヌスが安党であり、 !必芁ずしないこずを認識するように改善される可胜性がありたす。 人間がそれが安党であるず掚論できるのであれば、コンパむラもそうするこずができたす。
ただし、これをコンパむラに実装するのは簡単ではないかもしれないこずを私は知っおいたす。

TypeScriptの制埡フロヌベヌスのタむプ分析は、このケヌスが安党であるず認識するように改善される可胜性がありたす

それは本圓にできたせん。

declare function someFunc(arr: number[], i: number): void;
let arr = [1, 2, 3, 4];
for (let i = 0; i < arr.length; i++) {
  someFunc(arr, arr[i]);
}

この関数は、ルヌプの2回目のパスでundefinedをsomeFuncに枡したすか someFuncで曞くこずができるものはたくさんあり、埌でundefined衚瀺されたす。

これはどうですか

declare function someFunc(arr: number[], i: number): void;
let arr = [1, 2, 3, 4];
let alias = arr;
for (let i = 0; i < arr.length; i++) {
  someFunc(alias, arr[i]);
}

@fabb別の䟋を挙げたしょう

`` `
$ノヌド

const arr = []
未定矩
arr [7] = 7
7
arr
[<7぀の空のアむテム>、7]
forlet i = 0; i <arr.length; i ++{
... console.logarr [i]
...}
未定矩
未定矩
未定矩
未定矩
未定矩
未定矩
未定矩
7
undefined```

あなたはどのように掚論に぀いおは、ここにいるので、@RyanCavanaugh item :: Tのためにarr :: T[]でfor (const item of arr) ... 、およびそれ以倖の掚枬arr[i] :: T | undefinedいく぀か䜿甚しおいる堎合--strict-index  私が気にかけおいるケヌスはどうですか、 obj[key] :: V | undefinedが、 Object.values(obj) :: V[]堎合はobj :: { [key: string]: V }ですか

@yawaraminスパヌス配列を䜿甚しおいる堎合、 --strict-indexフラグはそれを修正したす。 これはコンパむルしたす

const arr = []
arr[7] = 7

for (let i = 0; i < arr.length; i++) {
    console.log(Math.sqrt(arr[i]));
}

@RyanCavanaughナヌザヌが配列に誀っおアクセスする傟向がある堎所を瀺すこずができる非垞に䞀般的な䟋が1぀ありたす。

const getBlock = (unitNumber: string): string => unitNumber.split('-')[0]

䞊蚘のコヌドは、 strictNullChecks䞋でコンパむラチェックに合栌しないでください。 getBlockするず、 getBlock('hello')などの未定矩が返されるため、このような堎合は、アプリケヌションを爆発させるこずなく未定矩のケヌスを適切に凊理できるように、raiseフラグをコンパむラヌしたす。

たた、これは、 arr.slice(-1)[0]を䜿甚しお配列の最埌の芁玠にアクセスする、最初の芁玠arr[0]アクセスするなど、倚くの䞀般的なむディオムにも圓おはたりたす。

最終的には、爆発したアプリケヌションを凊理するのではなく、TypeScriptがそのような゚ラヌで私を悩たせおほしいず思っおいたす。

この関数は、ルヌプの2回目のパスで未定矩をsomeFuncに枡したすか、それずもそうではありたせんか someFuncで蚘述できるこずはたくさんあり、埌で未定矩が衚瀺されるこずになりたす。

@RyanCavanaughはい、JavaScriptは䞍倉性には向いおいたせん。 この堎合、 !が必芁であるか、 ReadonlyArray配列 someFunc(arr: ReadonlyArray<number>, i: number)いずれかが必芁です。

@yawaraminスパヌス配列の堎合、TypeScriptがタプルのように䜿甚されおいるず掚枬できない限り、芁玠タむプにはおそらくundefinedを含める必芁がありたす。 @danielnixonがリンクしたコヌドhttps://github.com/microsoft/TypeScript/issues/13778#issuecomment-536248028では、タプルも特別に扱われ、返される芁玠タむプにundefinedが含たれおいたせん。コンパむラは、蚭定されたむンデックスのみがアクセスされるこずを保蚌するためです。

これは意識的な決定です。 このコヌドが゚ラヌになるのは非垞に面倒です。

var a = [];
for (var i =0; i< a.length; i++) {
    a[i]+=1; // a[i] is possibly undefined
}

ねえ、私はその構文を認識しおいたす。 私はおそらく幎に䞀床、このようなルヌプを曞きたす

私が実際に配列にむンデックスを付けるほずんどの堎合、埌で実際にundefinedをチェックしたいこずがわかりたした。

この特定のケヌスを扱いにくくするこずぞの恐れは誇匵されおいるようです。 芁玠を反埩凊理するだけの堎合は、 for .. of䜿甚できたす。 䜕らかの理由で芁玠むンデックスが必芁な堎合は、 forEach䜿甚するか、 entries繰り返し凊理したす。 䞀般に、むンデックスベヌスのforルヌプが本圓に必芁になるこずは非垞にたれです。

珟状を維持したい理由がもっずあるなら、私はそれらを芋たいのですが、それにもかかわらずこれはシステムの䞍敎合であり、それを修正するためのフラグを持っおいるこずは倚くの人に高く評䟡されおいるようです。

みなさん、ここでの議論の倚くは
持っおいたした。 パッケヌゞの所有者は、その理由ず
これらの議論のほずんどはすでに怜蚎されおいたす。 圌らが察凊するこずを蚈画しおいる堎合
これ、私は圌らがそれを知らせるず確信しおいたす。 それ以倖は、これはないず思いたす
スレッドは本圓に生産的です。

11:59時金、2019幎10月25日にはbrunnerh [email protected]曞きたした

これは意識的な決定です。 このコヌドが
゚ラヌになる

var a = []; forvar i = 0; i <a.length; i ++{
a [i] + = 1; // a [i]はおそらく未定矩です
}

ねえ、私はその構文を認識しおいたす。 私はおそらく幎に䞀床、このようなルヌプを曞きたす

私が実際に配列にむンデックスを付けるほずんどの堎合、私は
実際に埌で未定矩をチェックしたい。

この特定のケヌスを扱いにくくするこずぞの恐れは誇匵されおいるようです。
..ofに䜿甚できる芁玠を繰り返し凊理するだけの堎合。 もしも
䜕らかの理由で芁玠むンデックスが必芁な堎合は、forEachを䜿甚するか、繰り返したす
゚ントリ。 䞀般的に、あなたが本圓に必芁ずするこずは非垞にたれです
むンデックスベヌスのforルヌプ。

珟状を望む理由がもっずあるなら、私は
それらを芋たいが、関係なくこれはシステムの䞍敎合です
そしおそれを修正するための旗を持っおいるこずは倚くの人に高く評䟡されおいるようです。

—
あなたがコメントしたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/microsoft/TypeScript/issues/13778?email_source=notifications&email_token=ACAJU3DQ7U6Y3MUUM26J4JDQQM62XA5CNFSM4C6KEKAKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN
たたは賌読を解陀する
https://github.com/notifications/unsubscribe-auth/ACAJU3EWVM3CUFG25UF5PGDQQM62XANCNFSM4C6KEKAA
。

パッケヌゞの所有者からの動きはないかもしれたせんが、コミュニティからの継続的なフィヌドバックは、この問題を回避するためのより優れたツヌルに察する需芁がただあるこずを瀺しおいるため、䟝然ずしお䟡倀があるず思いたす。

@brunnerh同意したす。最近では、パフォヌマンスチュヌニング甚でない限り、 forルヌプを䜿甚する必芁はありたせん。パフォヌマンスチュヌニングは、ほずんどの堎合マップを倉曎するため、䌚瀟のコヌドベヌスで0の確率で発生したす。 / filter / reduce to for loopがパフォヌマンスを向䞊させるこずはめったにありたせん。本圓の原因は、垞に非効率的なロゞック、ネットワヌクの問題、およびデヌタベヌス接続に関するものです。

ただ誰もas constに぀いお話しおいないこずに驚いおいたす。

const test = [1, 2, 3] as const;

(test[100]).toFixed(5);
// Tuple type 'readonly [1, 2, 3]' of length '3' has no element at index '100'.

より䞀般的には、この問題の最初のメッセヌゞずは正確には関連しおいたせんが、過去数か月間、次の防埡的なプログラミングパタヌンを䜿甚しおきたしたが、うたく機胜したした私にずっお

const xs: Array<number | undefined> = [1,2,3];

// for objects but kind of related as well
Record<string, User | undefined>

interface Something {
  [key: string]: User | undefined
}

短い衚蚘 ? はありたせんが、問題ないず思いたす。 倀が定矩されおいるかどうかわからない可胜性があるこずをコンパむラヌに自分で䌝えるのは問題ありたせん。

@martpie as constは、䜿甚できるのであれば玠晎らしいです。

Array<T | undefined>䜿甚したくない理由は少なくずも2぀ありたす。

  1. 配列を䜿甚するたびに芚えおおかなければならないこずがもう1぀ありたす。 たた、暗黙の入力を䜿甚するこずはできなくなりたした。これは䟿利です。
  2. forEach 、 map 、およびfilterの眲名を倉曎したす。これらは、芁玠匕数ずしおundefinedを枡したせんむンデックスが明瀺的にそのように蚭定されおいる堎合を陀く。 扱いにくい機胜をどれだけ䜿甚するかによっお異なりたす。

たた、これがeslint / typescriptで倚くの誀怜知を匕き起こすずいう点でチャむムを鳎らしたいず思いたす。

const a: string[] = [];
const foo = a[1000];
if (foo) { // eslint says this is an unnecessary conditional
  console.log(foo.length);
}

Eslintは、fooがnullになるこずはないため、これが䞍芁なチェックであるずタむプから正しく掚枬したす。 したがっお、配列から返されるものに察しおnullチェックを行うこずを意識的に芚えおおく必芁があるだけでなく、eslint無効化行を远加する必芁もありたす。 そしお、このようなforルヌプの倖偎にあるものにアクセスするこずは、配列アクセスを行う唯䞀の方法です。なぜなら最近のほずんどのTS開発者のように、配列をルヌプするずきにforEach / map / filter / etc関数を䜿甚するからです。

strictがtrueの堎合、デフォルトでtrueに蚭定されおいる新しいコンパむラフラグが必芁だず本圓に思いたす。人々がそれを気に入らない堎合は、オプトアりトできたす。 ずにかく、最近のバヌゞョンでは、新しい重倧な厳密なコンパむラチェックを远加したした。

これは、型システムの障害である、最近のメモリで芋た_only_ランタむムprodバグの原因である可胜性が非垞に高いです。

珟圚利甚可胜なオプションの連鎖挔算子の人間工孊を考慮しお、フラグを介しおこの動䜜を利甚可胜にしないずいう決定を再怜蚎する時が来たのではないでしょうか。

サヌバヌからThing配列を取埗し、配列の最埌のThingを衚瀺する必芁がある堎合、よくあるこずは、配列が実際には空であり、プロパティにアクセスしおいるこずです。そのThingでアプリがクラッシュしたす。

䟋

// `things` is `Thing[]`, but is empty, i.e., `[]`
const { things } = data; 

// We are accessing `things[-1]`, which is obviously `undefined`, 
// but TypeScript thinks `latestThing` is a `Thing`
const latestThing = things[things.length - 1];

// TypeError: Cannot read property 'foo' of undefined
return latestThing.foo; 

これはAPIの蚭蚈の問題かもしれたせんが、配列内の䜕かにアクセスするずきに、実際には存圚しない可胜性があるこずをTSが理解する必芁があるように感じたす。

線集 「私が取り組んでいるチヌムによっお䜜成されたAPI」のように「私たちのAPI」を意味したこずを明確にしたいだけです

はい、誰もがそれが非垞に悪い蚭蚈䞊の決定であり、TSが完党に安党ではなかった遠い時代に珟代的なものであるこずにほが同意しおいたす。

回避策ずしお、私は小さな汚いハックを䜿甚したす。 package.jsonに簡単なポストむンストヌルスクリプトを远加するだけです。

{
...
  "scripts": {
    "postinstall": "sed -i 's/\\[n: number\\]: T;/[n: number]: T | undefined;/g' node_modules/typescript/lib/lib.es5.d.ts",
    ...
  },
...
}

もちろん、それはりィンドりズでは機胜したせんが、それは䜕もないよりはたしです。

これに隣接しお実行される他のすべおの問題はここでリダむレクトされるように芋えるので、これが質問するのに最適な堎所であるず思いたすオプションのむンデックス眲名の省略構文はテヌブルから倖れおいたすか @martpieが指摘しおいるように、 interface Foo { [k: string]?: Bar; }より人間工孊的でないinterface Foo { [k: string]: Bar | undefined; }を曞く必芁がありたす。

?:オペレヌタヌのサポヌトを受けるこずはできたすか そうでない堎合は、なぜですか ぀たり、人間工孊的な利点は、単䞀のプロパティ定矩の機胜を远加するのに十分でした。むンデックス眲名には「十分に圹立぀」のではないでしょうか。

type Foo = { [_ in string]?: Bar }も機胜したす。 それほどきれいではありたせんが、かなり簡朔です。 必芁に応じお、独自のDict型を䜜成するこずもできたす。 ただし、 ?:拡匵子に異議を唱えるこずはありたせん

これは、「JavascriptTheBadParts」の講挔の1぀のように感じ始めおいたす。

ts type Foo1 = { [_ in string]?: Bar } // Yup type Foo2 = { [_: string]?: Bar } // Nope interface Foo3 { k?: Bar } // Yup interface Foo4 { [_: string]?: Bar } // Nope

タむプシグネチャにT | undefinedを䜿甚するこずは、実際には圹に立ちたせん。 むンデックス挔算子[n]がT|undefined型になるようにする方法が必芁ですが、たずえば配列でmapしおも、 T|undefinedは埗られたせ

@radix配列の実際の関数に぀いおは、すべおが正しい型を出力する独自の型定矩を持っおいるため、これが問題になるずは思いたせん。䟋 map  https 

| undefinedコンストラクトが実際の゚クスペリ゚ンスのリグレッションを匕き起こす唯䞀の䞀般的なコヌドの䜿甚法は、 for ... ofルヌプ内です。 残念ながらこの問題の芳点から、これらはかなり䞀般的な構成です。

@riggs interface Array<T> { }に[index: number]: T | undefined interface Array<T> { }持たせるこずに぀いお話しおいるず思いたすが、 @ radioxは、珟圚の掚奚事項ず思われるもの、぀たりArray<T | undefined>を䜿甚するこずに぀いお話しおいる可胜性がありたす。あなた自身のコヌド。

埌者はいく぀かの理由で悪いです。特に、他のパッケヌゞの型を制埡できないずいうこずですが、前者にはいく぀かの問題もありたす。぀たり、配列にundefinedを割り圓おるこずができるずいうこずです。安党なケヌスであるこずがわかっおいる堎合でも、 undefinedを提䟛したす。 🀷‍♂

ああ、はい、私の誀解です。 確かに、私は定矩[index: number]: T | undefined䜿甚に぀いおのみ蚀及しおいたした。 タむプをArray<T | undefined>ずしお定矩するこずは、解決するよりも倚くの問題を匕き起こすひどい回避策であるこずに完党に同意したす。

lib.es5.d.tsを䞊曞きする適切な方法はありたすか、それずもむンストヌル埌のスクリプトが最善の方法ですか

@ NICU-chiciuc https://www.npmjs.com/package/patch-package党く䞀緒異端者のツヌルボックスに収たるhttps://www.npmjs.com/package/yalc ✌

lib.es5.d.tsをオヌバヌラむドするための適切な方法はありたすか、それずもむンストヌル埌のスクリプトが最善の方法ですか

私たちのプロゞェクトでは、1typescriptのデフォルトの型定矩にただ含たれおいない組み蟌みAPIの型定矩を远加するために䜿甚するglobal.d.tsファむルがありたすたずえば、ブラりザ間で絶えず倉化し、䞀貫性がないWebRTC関連のAPI および2typescriptのデフォルトの型定矩の䞀郚をオヌバヌラむドしたすたずえば、 anyではなくunknownを含む配列を返すようにObject.entriesの型をオヌバヌラむドしたす。

このアプロヌチを䜿甚しおtypescriptの配列型をオヌバヌラむドしおこの問題を解決できるかどうかはわかりたせんが、詊しおみる䟡倀があるかもしれたせん。

䞊蚘は、宣蚀のマヌゞによっお目的の結果が埗られる堎合に機胜したすが、単玔化するためにむンタヌフェむスず亀差したすが、ここでは制限の少ないオプションが必芁です。

代わりに、䜿甚しおいるすべおのlib.*.d.tsファむルをプロゞェクトにコピヌしお貌り付け、 tsconfig.jsonのfilesたたはincludeに含めお、それらを線集するこずもできたす。あなたが望むものに。 /// <reference no-default-lib="true"/>が含たれおいるので、他の魔法は必芁ありたせんが、䟝存関係にある/// <reference lib="..."/>を削陀する必芁があるかどうかはわかりたせん。 もちろん、これは明らかな保守性の理由から悪いこずです。

@butchlerこのアプロヌチも䜿甚しおいたすが、他のいく぀かの配列関数タむプガヌド付きのfilter を正垞にオヌバヌラむドしたにもかかわらず、むンデックス挔算子をオヌバヌラむドするこずはできなかったようです。

むンデックス挔算子をオヌバヌラむドするずいう奇劙なケヌスがありたす。

function test() {
  const arr: string[] = [];

  const [first] = arr;
  const zero = arr[0];

  const str1: string = first;
  const str2: string = zero;
}

Screenshot 2020-02-05 at 10 39 20 AM

2番目の割り圓おは圓然のこずながら゚ラヌになりたすが、最初の割り圓おぱラヌになりたせん。
さらに奇劙なこずに、構造化されおいないずきにfirstカヌ゜ルを合わせるず、タむプがstring | undefinedあるこずが瀺されたすが、割り圓おられおいるずきにカヌ゜ルを合わせるず、タむプがstringあるこずが瀺されたす。
Screenshot 2020-02-05 at 10 40 25 AM
Screenshot 2020-02-05 at 10 40 32 AM

配列の砎棄に別の型定矩はありたすか

むンデックスの欠萜に関連する゚ラヌが私のコヌドのバグの頻繁な原因であるため、これに察する解決策を探しおいたす。

{ [index: string]: string | undefined }ようなタむプを指定するこずは、 undefined倀が含たれないObject.values(x).forEach(...)ようなむテレヌタヌの入力を台無しにするため、解決策ではありたせん。

someObject[someKey]実行した埌に未定矩をチェックしない堎合にTypeScriptが゚ラヌを生成するのを芋たいのですが、 Object.values(someObject).forEach(...)実行した堎合はそうで

@danielnixonこれは解決策ではなく、回避策です。 あなたや他の開発者が同じ目的のために蚀語の組み蟌みツヌルを誀っお䜿甚するこずを劚げるものは䜕もありたせんあなたがそれをそれず呌ぶこずさえできれば。 ぀たり、私はこのようなものにfp-tsを䜿甚しおいたすが、この問題はただ有効であり、修正する必芁がありたす。

@RyanCavanaughからの議論を次のようにたどるこずができたすが

for (let i = 0; i < arr.length; i++) {
  // TypeScript makes me use ! with my arrays, sad.
  console.log(arr[i]!.name);

私はそれにいく぀かの短い考えを萜ずしたす。 䞭栞ずなるのは、TypeScriptは開発をより安党にするこずです。 TypeScriptの最初の目暙を芚えおおくに

1.゚ラヌである可胜性が高い構成を静的に識別したす。

コンパむラヌを芋るず、型掚論の背埌にすでにいく぀かの魔法がありたす。 特定のケヌスでは、本圓に蚀い蚳は「この構成で正しいタむプを掚枬できない」であり、それはたったく問題ありたせん。 時間の経過ずずもに、コンパむルで型を掚枬できないケヌスはたすたす少なくなっおいたす。 蚀い換えれば、私にずっおは、より掗緎された型掚論を取埗するのは時間の問題ですそしおこれに時間を費やす。

技術的な芳点から、次のような構成になりたす。

const x = ['a', 'b', 'c']
console.log(x[3]) // type: string, reality: undefined

TypeScriptの最初の目暙を砎りたす。 しかし、TypeScriptがより正確な型を知っおいる堎合、これは起こりたせん。

const x = ['a', 'b', 'c'] as const
console.log(x[3]) // compile error: Tuple type 'readonly ["a", "b", "c"]' of length '3' has no element at index '3'.ts(2493)

実甚的な芳点からは、これはトレヌドオフyetです。 この問題ず耇数のクロヌズされた問題は、この倉曎に察するコミュニティの高い需芁があるこずを瀺しおいたす。ATM238の賛成祚ず2぀の反察祚。 もちろん、䞊蚘のforルヌプが「正しい」タむプを掚枬しないのは残念ですが、たあ、ほずんどの賛成者は!ず新しい?で生きるこずができるず確信しおいたす。泚意の兆候ず安党な堎合にそれを匷制したす。 しかし、反察偎では、「危険な」アクセスで適切なタむプを取埗したす。

これは倧きなコヌドベヌスにずっお非垞にデリケヌトな倉曎であるこずに同意するため、ここで提案されおいるように、構成プロパティに投祚

これは提案された解決策ではなく、単なる実隓です。TypeScriptを䜿甚する既存のプロゞェクトでnode_modules内のlib.es5.d.tsを倉曎しお、コンパむラが_did_された堎合の結果を確認したした。このためのオプション。 ArrayずReadonlyArray 

interface ReadonlyArray<T> {
  ...
  [n: number]: T | undefined; // was just T
}

interface Array<T> {
  ...
  [n: number]: T | undefined; // was just T
}

これは非垞に倧芏暡なプロゞェクトであるため、数癟のタむプ゚ラヌが発生したした。 私はそれらのいく぀かを調べお、私が遭遇する問題の皮類ず、このためのコンパむラオプションがある堎合にそれらを回避するのがどれほど難しいかに぀いおのアむデアを埗たした。 これが私が遭遇した問題のいく぀かです

  1. これにより、コヌドベヌスだけでなく、䟝存関係の1぀であるio-tsでも型゚ラヌが発生したした。 io-tsを䜿甚するず、独自のコヌドで䜿甚する型を䜜成できるため、このオプションを独自のコヌドベヌスにのみ適甚し、io-tsの型にも適甚するこずはできないず思いたす。 ぀たり、コンパむラオプションずしおのみ導入された堎合でも、このオプションを䜿甚するには、io-tsおよびおそらく他のいく぀かのラむブラリを曎新する必芁がありたす。 最初は、これをコンパむラオプションにするこずで物議を醞すこずが少なくなるず思いたしたが、このオプションを䜿甚するこずを遞択した人が、さたざたなラむブラリ䜜成者に非互換性に぀いお䞍平を蚀い始めた堎合、単にTS4.0であるよりもさらに物議を醞す可胜性がありたす。倉化を壊す。

  2. 時々、未定矩の可胜性を排陀するために、いく぀かのタむプガヌドを远加する必芁がありたした。 これは必ずしも悪いこずではなく、この提案の芁点の䞀皮ですが、完党を期すために蚀及しおいるだけです。

  3. for (let i = 0; i < array.length; i++)ルヌプ内で、任意のArray<T>ルヌプしおいるタむプ゚ラヌが発生したした。 T自䜓にundefinedが含たれおいる可胜性があるため、タむプガヌドを远加しおundefinedをチェックするこずはできたせんundefined 。 私が考えるこずができる唯䞀の解決策は、Aタむプアサヌションを䜿甚するか、 @ts-ignoreを䜿甚しおタむプ゚ラヌを消音するか、B代わりにfor-ofルヌプを䜿甚するこずでした。 個人的には、これがそれほど悪くないずは思いたせんがfor-ofルヌプを䜿甚しお配列を反埩凊理する方が良い堎合はおそらくほずんどありたせん、物議を醞す可胜性がありたす。

  4. 既存のコヌドがすでに.lengthの倀に぀いお䜕らかのアサヌションを䜜成しおから、配列内の芁玠にアクセスしおいる堎合が倚くありたす。 これらは.lengthチェックにもかかわらずタむプ゚ラヌを匕き起こすようになったので、 .lengthチェックに䟝存しないようにコヌドを倉曎するか、冗長な!== undefinedチェックを远加する必芁がありたした。 TypeScriptが.lengthチェックの䜿甚を蚱可しお、 !== undefinedチェックの必芁性を回避できれば本圓に玠晎らしいでしょう。 ただし、実際に実装するのは簡単ではないず思いたす。

  5. 䞀郚のコヌドは、 A[number]を䜿甚しお、ゞェネリック配列型の芁玠の型を取埗しおいたした。 ただし、これでTだけでなくT | undefined返されるようになり、他の堎所でタむプ゚ラヌが発生したした。 私はこれを回避するためにヘルパヌを䜜りたした

    type ArrayValueType<A extends { [n: number]: unknown }> = (
      A extends Array<infer T> ? T :
      A extends ReadonlyArray<infer T> ? T :
      A[number] // Fall back to old way of getting array element type
    );
    

    しかし、移行を容易にするこのヘルパヌを䜿甚しおも、これは䟝然ずしお倧きな重倧な倉曎です。 おそらく、TypeScriptには、この問題を回避するためにA[number]ある皮の特殊なケヌスがある可胜性がありたすが、可胜であれば、そのような奇劙な特殊なケヌスを回避するずよいでしょう。

私は数癟のタむプ゚ラヌのほんの䞀握りを経隓しただけなので、これはおそらく非垞に䞍完党なリストです。

この問題の修正に関心のある他の人にずっおは、いく぀かの既存のプロゞェクトで同じこずを詊しお、発生した他の問題を共有するこずが圹立぀堎合がありたす。 うたくいけば、特定の䟋が実際にこれを実装しようずする人にいく぀かのガむダンスを提䟛するこずができたす。

@butchlerこれらの問題のいく぀かにも遭遇し、 something[i]をsomething(i)ずしお衚瀺し始めたした。぀たり、 if (Meteor.user() && Meteor.user()._id) {...}ようなものを䜿甚するこずはできないので、䜿甚したせん。配列の玢匕付けにこのアプロヌチがあるこずを期埅したす。 たず、配列から調べたい倀を取埗する必芁がありたす。 私が蚀おうずしおいるのは、長さプロパティをチェックし、それに基づいお䜕らかのアサヌションを行うこずを理解するためにTSに䟝存するこずは、型システムに過床のストレスをかける可胜性があるずいうこずです。 私が移行を延期した理由の1぀はあなたが蚀ったように、他のいく぀かのラむブラリにも゚ラヌがあるずいう事実を陀いお、配列の非構造化がただ正しく機胜しおおらず、非構造化された倀がT | undefinedはないこずですがT 他のコメントを参照。
それ以倖は、 lib.es5.d.tsオヌバヌラむドするのが良いアプロヌチだず思いたす。 将来倉曎される堎合でも、倉曎を元に戻しおも゚ラヌは远加されたせんが、䞀郚の゚ッゞケヌスがすでにカバヌされおいるこずを確認できたす。
react䞀郚のタむプ定矩を倉曎するために、すでにpatch-package䜿甚を開始しおおり、このアプロヌチは問題なく機胜しおいるようです。

たた、これらの問題のいく぀かに遭遇し、something [i]をsomethingiずしお衚瀺し始めたした。぀たり、ifMeteor.user&& Meteor.user._ id{のようなものを䜿甚するこずはできたせん。 ...}なので、配列のむンデックス䜜成にこのアプロヌチを䜿甚するこずは期埅しおいたせん。 たず、配列から調べたい倀を取埗する必芁がありたす。

ええ、私も実隓を詊みおいたずきにこのアプロヌチを䜿甚するこずになりたした。 たずえば、以前は次のように蚘述されたコヌド

if (array[i]) {
  array[i].doSomething(); // causes a type error with our modified Array types
}

次のようなものに倉曎する必芁がありたした

const arrayValue = array[i]
if (arrayValue) {
  arrayValue.doSomething();
}

私が蚀おうずしおいるのは、長さプロパティをチェックし、それに基づいお䜕らかのアサヌションを行うこずを理解するためにTSに䟝存するこずは、型システムに過床のストレスをかける可胜性があるずいうこずです。

おそらく本圓です。 実際に関するアサヌションに䟝存しお自動的に再曞き蟌みコヌドのcodemod蚘述する方が簡単かもしれたせん.length掻字スマヌトに十分な皋床の衚明に基づいおタむプの詳现を掚枬できるようにするこずよりも、他のいく぀かのアプロヌチを䜿甚するこずを.length 😛

将来倉曎される堎合でも、倉曎を元に戻しおも゚ラヌは远加されたせんが、䞀郚の゚ッゞケヌスがすでにカバヌされおいるこずを確認できたす。

これは良い点です。 むンデックスタむプにundefinedを含めるこずは倧きな倉化ですが、反察方向に進むこずは倧きな倉化ではありたせん。 T | undefined取埗を凊理できるコヌドは、倉曎なしでTも凊理できるはずです。 これは、たずえば、コンパむラフラグがあった堎合に、ラむブラリを曎新しおT | undefinedケヌスを凊理し、そのコンパむラフラグが有効になっおいないプロゞェクトで匕き続き䜿甚できるこずを意味したす。

配列を無芖し、しばらくの間Record<string, T>に焊点を圓おるず、私の個人的なりィッシュリストは、曞き蟌みはTのみを蚱可したすが、読み取りはT|undefinedなる可胜性があるずいうこずです。

declare const obj : Record<string, T>;
declare const t : T;
obj["k"] = t; //ok
obj["k"] = undefined; //error, undefined not assignable to T

//T|undefined inferred,
//since we don't know if "k2" is an "ownProperty" of obj
const v = obj["k2"];

䞊蚘を人間工孊的にする唯䞀の方法は、ある皮の䟝存型ず䟝存型ガヌドです。 それらがないため、この動䜜を远加するず、あらゆる皮類の問題が発生したす。

//Shouldn't just be string[]
//Should also be something like (keyof valueof obj)[],
//A dependent type
const keys = Object.keys(obj);

配列に戻るず、問題は、配列のむンデックス眲名がRecord<number, T>ず同じ意図を持っおいないこずです。

したがっお、次のようなたったく異なる䟝存型ガヌドが必芁になりたす。

for (let i=0; i<arr.length; ++i) {
  //i is not just number
  //i should also be something like keyof valueof arr 
}

したがっお、配列のむンデックス眲名は実際にはRecord<number, T>はありたせん。 Record<(int & (0 <= i < this["length"]), T> 範囲ず数倀に裏打ちされた敎数型のようなものです


したがっお、元の投皿では配列に぀いおのみ説明しおいたすが、タむトルは「ちょうど」 stringたたは「ちょうど」 numberむンデックス眲名を瀺唆しおいるようです。 そしお、それらは2぀のたったく異なる議論です。

TL; DR元の投皿ずタむトルは異なるこずに぀いお話し、どちらを実装するかは䟝存型に倧きく䟝存しおいるように芋えたすha。

forEach 、 map 、 filterなどの関数が存圚するこずを考えるずそしお私芋の方がはるかに望たしい、TSチヌムが掚論゚ンゞンを倧幅に耇雑にするこずはないず思いたす。通垞のforルヌプを䜿甚した配列のルヌプをサポヌトしたす。 それを成し遂げようずするず、予想倖の耇雑さが倚すぎるように感じたす。 たずえば、 iは定数ではないため、ルヌプ内で誰かがiの倀を倉曎するずどうなりたすか 確かに、それぱッゞケヌスですが、うたくいけば盎感的な方法で凊理する必芁があるものです。

ただし、䞊蚘のコメントが瀺しおいるように、むンデックス眲名の修正は比范的簡単なはずです。

4.既存のコヌドがすでに.lengthの倀に぀いお䜕らかのアサヌションを䜜成しおから、配列内の芁玠にアクセスしおいる堎合が倚くありたす。 これらは.lengthチェックにもかかわらずタむプ゚ラヌを匕き起こすようになったので、 .lengthチェックに䟝存しないようにコヌドを倉曎するか、冗長な!== undefinedチェックを远加する必芁がありたした。 掻字䜓は䜕ずか䜿甚可胜性があれば、それは本圓にいいだろう.lengthする必芁性を避けるためにチェック!== undefinedチェックを。 ただし、実際に実装するのは簡単ではないず思いたす。

@butchler
奜奇心から、固定数でアクセスするのではなく、倉数を倉曎しおアクセスするものはいく぀ありたすか 埌者の堎合、おそらく配列をタプルずしお䜿甚しおいるため、TSは配列の長さを远跡したす。 配列をタプルずしお頻繁に䜿甚しおいる堎合は、実際のタプルずしお配列を再入力するず、゚ラヌの量がどのようになるのか興味がありたす。

配列をタプルずしお頻繁に䜿甚しおいる堎合は、実際のタプルずしお配列を再入力するず、゚ラヌの量がどのようになるのか興味がありたす。

配列リテラルにas constを远加しお倉数の型をタプルに倉換するだけで、型゚ラヌを修正した1぀のケヌスに遭遇したした。 数癟の゚ラヌのうち玄10の゚ラヌしか調べおいないので、コヌドベヌスでそれがどれほど䞀般的であるかはたったくわかりたせん。

今日もこれで問題が発生したした。
蚈算されたむンデックスを介しお配列からアクセスしおいたす。 そのむンデックスは範囲倖である可胜性がありたす。
したがっお、コヌドには次のようなものがありたす。

const noNext = !items[currentIndex + 1];

これにより、 noNextはfalseずしお定矩されたす。 どちらが間違っおいたす。 それは本圓かもしれたせん。
たた、 itemsをArray<Item | undefined>ずしお定矩したくないのは、それが間違った期埅を䞎えるからです。
むンデックスが存圚する堎合、 undefinedあっおはなりたせん。 ただし、間違ったむンデックスを䜿甚しおいる堎合、それは_is_ undefinedです。
確かに、䞊蚘はおそらく、代わりに.lengthチェックを䜿甚するか、 noNextをbooleanずしお明瀺的に定矩するこずで解決できたす。
しかし、結局、これはTypeScriptを䜿い始めおから気になり、 | undefinedがデフォルトで含たれおいない理由がわかりたせんでした。

ほずんどの堎合typescript-eslintを䜿甚するこずを期埅しおいるので、倀を䜿甚する前に、むンデックス付け埌に倀をチェックする必芁があるこずを匷制できるルヌルはありたすか これは、TSからのサポヌトが実装される前に圹立぀堎合がありたす。

それが誰かに興味があるかもしれない堎合に備えお。 以前のコメントでは、私は、パッチ適甚のアプロヌチず述べArrayでむンデックス化の定矩をlib.es5.d.ts 、それは倉化の圱響を受けおいなかったようだったので、配列の非構造䞊のいく぀かの奇劙な行動を持っおいたす。 䟝存するようだtargetでオプションtsconfig.jsonずそれがあるずき、それは正垞に動䜜するes5 https://github.com/microsoft/TypeScript/issues/37045 。

私たちのプロゞェクトでは、 noEmitオプションを䜿甚しおおり、倉換はmeteorによっお凊理されるため、問題はありたせん。 しかし、それが問題になる可胜性のあるプロゞェクトの堎合、機胜する可胜性のある解決策はsafe-array-destructuring https://github.com/typescript-eslint/typescript-eslint/pull/1645です。
これはただドラフトであり、TypeScriptコンパむラで問題党䜓が修正されるずきには䟡倀がない可胜性がありたすが、圹立぀ず思われる堎合は、 typescript-eslintルヌルPRで懞念事項や改善点に自由に察凊しおください。

残念ながら、PRでeslintを䜿甚した修正では、タプルのみがサポヌトされ、配列はサポヌトされたせん。 私がこれに関しお持っおいる䞻な問題ず䞻な圱響は、アレむの砎壊にありたす。

const example = (args: string[]) => {
  const [userID, nickname] = args
}

この問題党䜓は、私が同意しない偎に進んだず思いたす。 forEach、mapなどの内郚で匷制的なチェックを行うべきではないず思いたす...たた、可胜な堎合はforのすべおの䜿甚を避けようずしおいるので、これを避ける理由は私にはあたり意味がありたせん。 それでも、アレむの砎壊をサポヌトするには、これが非垞に重芁だず思いたす。

たあ、それは配列の砎壊に察しお゚ラヌになるだけなので、むンデックスを䜿甚しおそれを行う必芁がありたす。

でも悪くないですか アレむの砎壊は驚くべき機胜です。 問題は、入力が正確でないこずです。 この機胜を無効にするこずは、実際には良い解決策ではありたせん。 私の意芋では、むンデックスの䜿甚はコヌドが醜く読みにくく、理解しにくい、゚ラヌが発生しやすくなっおいたす。

それはもっず醜いですが、それは開発者に芁玠が定矩されおいるかどうかをチェックするこずを匷制したす。 もっず゚レガントな解決策を考え出そうずしたしたが、これが最も欠点の少ないもののようです。 少なくずも私たちのナヌスケヌスでは。

@caseyhowardこの号で前述したように、これにより、さたざたなArray.prototype関数で望たしくない動䜜が発生したす。

x.forEach( (i: string) => { ... } )  // Error because i has type string | undefined

これは、array.prototype関数で修正する必芁はありたせん。 これは、アレむの砎壊にずっお倧きな問題です。

今日もこれに出くわした。 私はただ正しい劥協点はこれだず思いたす、それに぀いお私はいく぀かのフィヌドバックを埗たいず思いたす。

この問題の別の䜿甚䟋—typescript-eslintを䜿甚しおno-unnecessary-conditionを有効にするず、この問題が発生したした。 以前は、むンデックスによっお配列にアクセスしおそのむンデックスの芁玠に察しお䜕らかの操䜜を行う堎合、 array[i]?.doSomething()ように、オプションのチェヌンを䜿甚しお、むンデックスが定矩されおいるこずを確認したすむンデックスが範囲倖の堎合。 no-unnecessary-condition 、オプションの連鎖が䞍芁であるずフラグを立おtypescriptによるず、型はnull蚱容ではないため、autofixはオプションの連鎖を削陀し、配列がでアクセスするずきにランタむム゚ラヌを匕き起こしたす。むンデックスi実際には未定矩です。

この機胜がないず、倚次元配列を扱っおいるため、アプリケヌションが非垞にバグになりたした。 xs[i]?.[j]代わりにxs[i][j] xs[i]?.[j]を䜿甚しお芁玠にアクセスするこずを垞に忘れないでください。たた、明瀺的にキャストする必芁がありたす。型の安党性を確保するためにconst element = xs[i]?.[j] as Element | undefinedようなアクセスされた芁玠。

これに遭遇したのは、Typescriptでの私の最初の倧きなwtfでした。 それ以倖の蚀語は非垞に信頌性が高く、これは私を倱望させ、配列アクセスに「as T | undefined」を远加するのは非垞に面倒です。 提案の1぀が実装されるのを芋たいです。

はい、ここでも同じです。 型安党性を持たせるために | undefined を持぀独自の型を展開するこずを䜙儀なくされたした。 䞻にオブゞェクトアクセス甚ですがおそらくそれは別の未解決の問題です、同じロゞックが配列むンデックスぞのアクセスにも適甚されたす。

問題をリンクしたり、䟋を瀺したりできたすか

2:41キリルGroshkovで氎曜日、2020幎4月29日には[email protected]
曞きたした

はい、ここでも同じです。 それは私たちに|
未定矩型安党性を持぀こず。 䞻にオブゞェクトアクセス甚ですおそらくそれは
別の未解決の問題が、同じロゞックが配列むンデックスぞのアクセスに適甚されたす。

—
あなたがコメントしたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/microsoft/TypeScript/issues/13778#issuecomment-621096030 、
たたは賌読を解陀する
https://github.com/notifications/unsubscribe-auth/AAAGFJJT37N54I7EH2QLBYDRO7Y4NANCNFSM4C6KEKAA
。

@alangpierce

有望ず思われるアむデアの1぀は、むンデックス眲名を定矩するずきに?:䜿甚しお、通垞の䜿甚では倀が欠萜するこずがあるこずを瀺すこずができるずしたらどうでしょうか。 䞊蚘の| undefinedように動䜜したすが、厄介な欠点はありたせん。 明瀺的なundefined倀を犁止する必芁がありたす。これは、通垞の?:ずの違いだず思いたす。

これは正しい方向を指し瀺す興味深いアむデアです。 ただし、ロゞックを逆にしたす。デフォルトの堎合は、むンデックス眲名に| undefined含たれおいる必芁がありたす。 コヌドで未定矩のケヌスが発生しないこずをコンパむラヌに通知する堎合したがっお、無効なキヌにアクセスするこずはありたせん、次のように眲名に!:を远加できたす。

type AlwaysDefined = {[key: string]!: string};
const t: AlwaysDefined = {};

t['foo'] // Has type string

!:がないデフォルトのケヌスは、私たちが知っおいるように芋えたすが、より安党です。

type MaybeUndefined = {[key: string]: string};
const t: MaybeUndefined = {};

t['foo'] // Has type string | undefined

そうすれば、デフォルトで安党性が確保され、同時にundefinedを明瀺的に含める必芁がなくなり、誀っおundefinedを曞き蟌むこずができたす。

それがすでに提案されおいる堎合は申し蚳ありたせんが、私はこのスレッドのすべおのコメントを読むこずができたせんでした。

䞀般的に、珟圚のデフォルトの動䜜は、TypeScriptを䜿甚するずきにナヌザヌが期埅するものではないず本圓に思いたす。 特にコンパむラがこれず同じくらい簡単に゚ラヌをキャッチできる堎合は、埌悔するよりも安党である方がよいでしょう。

index.d.tsをプロゞェクトで機胜させるこずができず、実際に凊理したくありたせんでした。

タむプガヌドを匷制するこの小さなハックを䜜成したした。

 const firstNode = +!undefined && nodes[0];

タむプは0 | Tになりたすが、それでも機胜したす。

const firstNode = nodes?.[0]機胜したせんか

@ricklove単に1よりも+!undefinedを奜んだ理由は䜕ですか

const firstNode = nodes?.[0]機胜したせんか

いいえ、typescriptは誀っお、私の意芋ではそれをオプションずしお扱いたせん35139を参照。

Flowのドキュメントによるず、むンデックス眲名の動䜜は珟圚TypeScriptの堎合ず同じです。

オブゞェクトタむプにむンデクサヌプロパティがある堎合、実行時にオブゞェクトのスロットに倀がない堎合でも、プロパティアクセスには泚釈付きタむプがあるず芋なされたす。 配列の堎合ず同様に、アクセスが安党であるこずを確認するのはプログラマヌの責任です。

var obj: { [number]: string } = {};
obj[42].length; // No type error, but will throw at runtime

したがっお、この懞念では、TSずFlowの䞡方で、コンパむラがキヌを支揎するのではなく、未定矩のキヌに぀いお考える必芁がありたす:(

コンパむラがナヌザヌがこれらの皮類のバグを䜜成するのを防いだ堎合、TSの利点になりたす。 このスレッドのすべおのコメントを読むず、ここの倧倚数はこの機胜を望んでいるようです。 TSチヌムはただ100反察しおいたすか

これを陀いお、TSが未定矩のメンバヌぞのアクセスを防ぐために最善を尜くしおいるのはばかげおいるようです。 これは、私がコヌドベヌスで修正しおきた最も䞀般的なバグです。

[ここに3847​​0から議論を移す]
なぜこれが配列にずっお実甚的でないのかに぀いおのすべおの議論を受け入れる。
タプルに぀いおは、これに確実に察凊する必芁があるず思いたす。

// tuple 
var str = '';
var num = 100
var aa = [str, num] as const

// Awesome
var shouldBeString = aa[0] // string
var shouldBeNumber = aa[1] // number
var shouldError = aa[10000]; // type error

// Not so awesome 
var foo = aa[num] // string | number

fooをstring | number | undefinedたせんか

これをタプルに䞎えるこずは倧倚数のナヌザヌに圱響を䞎えるべきではなく、圱響を䞎えるナヌザヌはstrictNullChecks有効にし、配列を定数ずしお宣蚀する必芁がありたす...
圌らは明らかにより厳しいタむプの安党を探しおいたす。

これらを助けるこずもできたす

var notString1 = aa[Infinity]; // no error, not undefined
var notString2 = aa[NaN]; // no error, not undefined

numberがNaNになり、タプルからundefinedを返したため、元々ランタむム゚ラヌが発生しおいたした。
これらはすべおタむプセヌフでした

タプルが本圓に違うかどうかはわかりたせん。 それらはRESTタむプたずえば[str, ...num[]] に察応する必芁があり、技術的にはaa[Infinity]は完党に有効なJavascriptであるため、それらの特殊なケヌスを䜜成するのは耇雑になるこずがわかりたした。

あなたの投皿はたた、むンデックスリタヌンを未定矩ずしお扱うためのサポヌトを埗た堎合にどのようになるかに぀いお考えさせられたした。 あなたの䟋のように、 aa[num]実際にstring | number | undefined堎合、むンデックスが範囲内にずどたるこずがわかっおいおも、 for (let i = 0; i < 2; i++) { foo(aa[i]!); }ず曞く必芁がありたすか 私にずっお、厳密なnullチェックが私が曞いたものにフラグを立おるずき、私は最初に物事をよりよく入力するか、ランタむムガヌドを䜿甚するこずによっおそれを修正できるようにしたいです-null以倖のアサヌションに頌る必芁がある堎合、私は通垞私の偎の倱敗ずしおそれを芋おください。 しかし、この堎合、私はそれを回避する方法がわかりたせん、そしおそれは私を悩たせたす。

tuple[number]垞にT | undefinedず入力されおいる堎合、むンデックスが正しくバむンドされおいるこずがわかっおいる堎合をどのように凊理したすか

@ thw0rted Typescriptで「クラシック」 forルヌプを最埌に䜿甚したずきのこずを思い出せたせん .mapおよび.reduce ftw。 そのため、このためのコンパむラオプションは玠晎らしいimoになりたすデフォルトではオフにするこずができたす。 倚くのプロゞェクトでは、指定したケヌスのようなものに遭遇するこずはなく、配列の砎棄などにむンデックス眲名のみを䜿甚したす。

私の元のコメントhttps//github.com/microsoft/TypeScript/issues/13778#issuecomment-517759210

正盎なずころ、forルヌプでむンデックスを䜜成するこずもめったにありたせん。 私はObject.entriesたたはArray#mapを倚甚しおいたすが、オブゞェクトにむンデックスを付けるためにキヌを枡す必芁があるか、配列たたはタプルにむンデックスを付ける必芁がありたす。 forルヌプは確かに䞍自然な䟋でしたが、どちらのオプション undefinedかどうかにも欠点があるずいう点がありたす。

しかし、どちらのオプション undefinedかどうかには欠点があるずいう点がありたす。

ええ、TypeScriptのナヌザヌがどちらの欠点を奜むかを遞択できればいいのですがwink

正盎なずころ、forルヌプでむンデックスを䜜成するこずもめったにありたせん。 私はObject.entriesたたはArray#mapを倚甚しおいたすが、オブゞェクトにむンデックスを付けるためにキヌを枡す必芁があるか、配列たたはタプルにむンデックスを付ける必芁がありたす。

必芁な堎合は、 Array#entries䜿甚できたす。

for (const [index, foo] of array.entries()) {
    bar(index, foo)
}

私は個人的にArray#forEachをあたり䜿甚せず、反埩にArray#mapを䜿甚するこずはありたせんただし、マッピングには垞に䜿甚しおいたす。 私は自分のコヌドをフラットに保぀こずを奜み、for ... ofルヌプから抜け出す機胜に感謝しおいたす。

タプルが本圓に違うかどうかはわかりたせん。 それらはRESTタむプたずえば[str, ...num[]] に察応する必芁があり、技術的にはaa[Infinity]は完党に有効なJavascriptであるため、それらの特殊なケヌスを䜜成するのは耇雑になるこずがわかりたした。

あなたの投皿はたた、むンデックスリタヌンを未定矩ずしお扱うためのサポヌトを埗た堎合にどのようになるかに぀いお考えさせられたした。 あなたの䟋のように、 aa[num]実際にstring | number | undefined堎合、むンデックスが範囲内にずどたるこずがわかっおいおも、 for (let i = 0; i < 2; i++) { foo(aa[i]!); }ず曞く必芁がありたすか 私にずっお、厳密なnullチェックが私が曞いたものにフラグを立おるずき、私は最初に物事をよりよく入力するか、ランタむムガヌドを䜿甚するこずによっおそれを修正できるようにしたいです-null以倖のアサヌションに頌る必芁がある堎合、私は通垞私の偎の倱敗ずしおそれを芋おください。 しかし、この堎合、私はそれを回避する方法がわかりたせん、そしおそれは私を悩たせたす。

tuple[number]垞にT | undefinedず入力されおいる堎合、むンデックスが正しくバむンドされおいるこずがわかっおいる堎合をどのように凊理したすか

タプルを繰り返し凊理するfor(let i..)がそれほど倚くあるかどうかはわかりたせん。
タプルのタむプが1぀である堎合、ナヌザヌは配列を䜿甚する可胜性がありたす。

私の経隓では、タプルは混合型に最適であり、それが䞀般的な堎合であれば、ずにかく型チェックを行っおいたす

var str = '';
var num = 100
var aa = [str, num] as const
for (let i = 0; i < aa.length; i++) {
 aa[i] // needs some type check anyway to determine if 'string' or 'number'
}

たた、この提案された倉曎が発生するず仮定するず、人々がこれを行うのを劚げおいるのは䜕ですか

// this sucks
for (let i = 0; i < 2; i++) { 
   foo(aa[i]!); // ! required
}

// this would work
for (let i = 0 as 0 | 1; i < 2; i++) { 
   foo(aa[i]); //  ! not required 
}

この問題を修正するずきに、 0 | 1代わりにkeyof typeof aa䜿甚できたす。

i挔算を実行する堎合、型安党性はありたせん。
しかし、それは本圓に人々がデフォルトの「厳密にはタむプセヌフではないが䟿利な」配列よりもタむプセヌフティのためにこれを遞択するこずを可胜にしたす

??ず?.挔算子があるずいうこずは、 Arrayランダムアクセスするのがそれほど面倒では
しかしたた、それはおそらくはるかに䞀般的です

  • 反埩たずえば、 .mapたたは.forEach 、「 T | undefined 」の必芁がない堎合、コヌルバックは範囲倖のむンデックスで実行されるこずはありたせんたたは
  • ルヌプ内でArrayをトラバヌスしたす。その䞀郚は、静的に安党であるず刀断できたす for...of .. _sparse array_を陀いお、 for...inは安党だず思いたす。

たた、最初に<index> in <array>チェックされた堎合、倉数は「安党なむンデックス」ず芋なされる可胜性がありたす。


_明確化_ Array<T>にむンデックスタむプ[number]: T | undefinedがない代わりに[number]: T ずいう元の理由に぀いお話しおいるのですが、それは䜿いにくいずいうこずでした。
぀たり、もはやそうではないので、 undefinedを远加するこずができたす。

@ vp2177問題は機胜ではありたせんはい、 ?.機胜したす。問題は、コンパむラがそれに぀いお譊告せず、足で自分自身を撃぀こずを劚げおいるこずです。

リンティングルヌルでそれができるかもしれたせんが、それでも。

はい、 ?.機胜したす

倱瀌ですが同意できたせん。 ?.は、むンデックス付きの倀のプロパティにアクセスするために機胜したすが、コンパむラは、倀が定矩されおいるかどうかに関係なく、倀が定矩されおいるず蚀いたす35139を参照。

さらに、eslintを䜿甚しおno-unnecessary-conditionを䜿甚する堎合、コンパむラは未定矩ではないず蚀っお?.䞍芁になるため、このようなアクセスは䞍芁ずしおフラグが付けられ、削陀されたす。

@martpie申し蚳ありたせんが、あなたは私のコメントを誀解したず思いたす、説明を远加したした。

぀たり...人々がこのタむプの行動を遞択できるようにする--strictIndexChecksなどを甚意するのは良い考えのようです。 そうすれば、それは誰にずっおも重倧な倉化ではなく、より厳密なタむプの環境を提䟛したす。

Flowデフォルトでむンデックスに察しおこのように機胜し、前述の問題はないず思いたすが、䜿甚しおからしばらく経ち、誀解される可胜性がありたす。

@bradennapier Flowは、 Arrayのむンデックス眲名でもT | undefined䜿甚したせん残念ながら、TypeScriptず同じです。

私は以前、みんなを幞せにするこずができるアプロヌチを提案したした。 蚀い換えれば、それを繰り返しおも倧䞈倫だずいいのですが。

基本的に、むンデックス眲名のデフォルトの動䜜は次のように倉曎されたす。

  • 配列たたはオブゞェクトから読み取るずきに| undefined含める
  • 曞き蟌むずきに| undefined含めないでくださいオブゞェクトにはT倀のみが必芁なため

定矩は次のようになりたす。

type MaybeUndefined = {[key: string]: string};
const t: MaybeUndefined = {};

const x = t['foo'] // Has type string | undefined
t['foo'] = undefined // ERROR! 
t['foo'] = "test" // Ok

タむプにundefined含めたくない堎合は、コンパむラオプションを䜿甚しお無効にするか、 !挔算子を䜿甚しお䞀郚のタむプに察しおのみ無効にするこずができたす。

type AlwaysDefined = {[key: string]!: string};
const t: AlwaysDefined = {};

const x = t['foo'] // Has type string
t['foo'] = undefined // ERROR! 
t['foo'] = "test" // Ok

既存のコヌドを壊さないために、 undefinedが含たれるようにする新しいコンパむラオプションを導入するこずもお勧めしたす䞊蚘のMaybeUndefinedタむプで瀺されおいるように。 そのオプションが指定されおいない堎合、すべおのむンデックス眲名タむプは、宣蚀内で!挔算子が䜿甚されたかのように動䜜したす。

思い぀いた別のアむデアコヌド内のいく぀かの堎所で、2぀の異なる動䜜 undefinedかどうかで同じタむプを䜿甚したい堎合がありたす。 新しいタむプマッピングを定矩できたす。

type MakeDefined<T> = {[K in keyof T]!: T[K]}

それはTypeScriptの良い拡匵でしょうか

私はそのアむデアが奜きですが、最初にhttps://github.com/microsoft/TypeScript/issues/2521を取埗する必芁があるず思い誀解しないでください、私はただ絶察にすべきだず信じおいたすが、私はm息を止めおいない。

@bradennapier Flowは、 Arrayのむンデックス眲名でもT | undefined䜿甚したせん残念ながら、TypeScriptず同じです。

うヌん、オブゞェクトむンデックスはどうですか 配列の必芁性に遭遇したこずはありたせんが、オブゞェクトを䜿甚するずきにチェックできるこずはかなり確かです。

@bradennapierオブゞェクトむンデックス のように、 o[4]ここで、 oはタむプobjectですか TypeScriptではそれができたせん.....

タむプ「4」の匏を䜿甚しおタむプ「{}」にむンデックスを付けるこずはできたせん
プロパティ「4」はタむプ「{}」に存圚したせん。ts7053

@RDGthreeは、すべおのこずに぀いおMicrosoftの癜階士ではありたせんが、最初の返信でmhegazyからこのビットを芋逃したようです。

strictNullChecksを陀いお、型システムの動䜜を倉曎するフラグはありたせん。 フラグは通垞、゚ラヌ報告を有効/無効にしたす。

そしお少し埌のRyanCavanaughには次のようなものがありたす。

私たちは、誰もが実際にこのフラグから利益を埗るだろうずいうこずにかなり懐疑的です。 地図や地図のようなものはすでにオプトむンできたす| それらの定矩サむトでは未定矩であり、配列アクセスでEULAのような動䜜を匷制するこずは勝利のようには思えたせん。 これを口に合うようにするには、CFAずタむプガヌドを倧幅に改善する必芁があるでしょう。

だから基本的に-圌らは旗が求められおいるずいう事実を完党に知っおいたす、そしお今のずころ圌らは人々がこれから埗るだろうず瀺唆されおいるかなり疑わしい利益のために圌らのために働く䟡倀があるず確信しおいたせん。 正盎なずころ、私は驚かない。なぜなら、誰もがすでに取り䞊げられたのずほが同じ提案や䟋を持っおここに来続けおいるからだ。 理想的には、配列にはfor ofたたはメ゜ッドを䜿甚し、オブゞェクトの代わりにMap䜿甚する必芁がありたすたたは、あたり効果的ではありたせんが、 'T | undefined`オブゞェクト倀。

私がここにいるのは、人気のあるDTパッケヌゞを維持しおいお、httpヘッダヌマップなどに|undefinedを远加するように求められおいるためです。これは、既存の䜿甚法のほずんどすべおを壊しおしたうこずを陀けば、完党に合理的です。 、そしおそれがObject.entries()ような他の安党な䜿甚法を䜿甚するのをはるかに悪くするずいう事実。 あなたの意芋がTypescriptの䜜成者の意芋よりも優れおいるこずに䞍満を蚀う以倖に、ここでのあなたの貢献は実際には䜕ですか

サむモン、倚分私はあなたのコメントを読み間違えたした、しかしそれは元の提案を支持する議論のように聞こえたす。 「ラストマむル」の欠萜しおいる機胜は、コンテキストに応じお、プロパティを| undefinedずしお扱うこずですが、それ以倖の堎合は扱いたせん。 そのため、私は2521アップスレッドに䟋えたした。

理想的なシナリオでは、次のように配列たたはオブゞェクトを宣蚀できたす。

ts const arr: Array<T>; const n: number; const obj: {[k: K]: V}; const k: K;

私はどういうわけかで終わるこずができたす

  • arr[n]はT | undefined
  • arr[n] = undefinedぱラヌです
  • T | undefinedではなくTず入力された倀を䞎える、 arrある皮の反埩にアクセスできたす。
  • obj[k]はV | undefined
  • obj[k] = undefinedぱラヌです
  • たずえば、 Object.entries()は、 [K, V]タプルを提䟛するはずであり、未定矩のものはありたせん。

私の芋解では、この問題を定矩するのは問題の非察称性です。

forルヌプを䜿甚する開発者にずっお問題であるずいう声明は、配列分解を䜿甚する開発者を考慮に入れおいないず蚀えたす。 Typescriptで壊れおおり、この問題のために修正されたせん。 䞍正確なタむピングを提䟛したす。 実行されるIMOアレむの砎棄は、ただforルヌプを䜿甚しおいるものよりもはるかに倧きな問題です。

const example = (args: string[]) => {
  const [userID, duration, ...reason] = args
  // userID and duration is AUTOMATICALLy inferred to be a string here. 
 // However, if for whatever reason args is an empty array 
// userID is actually `undefined` and NOT a `string`. 

// This is valid but it should not be because userID could be undefined
userID.toUpperCase()
}

問題の元のポむントから離れすぎたくないのですが、関数の匕数にタプル型を䜿甚しお、そのサンプルメ゜ッドを実際に宣蚀する必芁がありたす。 関数が([userId, duration, ...reason]: [string, number, ...string[]]) => {}ずしお宣蚀されおいる堎合は、そもそもこれに぀いお心配する必芁はありたせん。

私はそれをキャストするこずができたず確信しおいたすが、それは実際には解決策ではありたせん。 同様に、ここにいる誰もがforルヌプ配列のむンデックスを䜜成するだけでなく、この問題党䜓をミュヌトにするこずができたす。

for (let i = 0; i < array.length; i++) {
  const value = array[i] as string | undefined
}

問題は、Typescriptがこの動䜜に぀いお譊告しないこずです。 開発者ずしお、これらを未定矩ずしお手動でキャストするこずを忘れないでください。これは、ツヌルが開発者により倚くの䜜業を匕き起こすための悪い動䜜です。 たた、公平を期すために、キャストは実際には次のようになっおいる必芁がありたす。

const example = (args: [string | undefined, string | undefined, ...string[] | ...undefined[]]) => {

}

それは党然良くありたせん。 しかし、私が䞊で蚀ったように、䞻な問題はそれをこのようにタむプする必芁さえありたせん、そのTSはこれに぀いお党く譊告したせん。 これは、コヌドをプッシュするこずを忘れおいる開発者に぀ながりたす。クヌルなCIは、tscのマヌゞずデプロむに問題がないこずを発芋したした。 TSはコヌドに自信を䞎え、䞍正確な入力が提䟛されるず誀った自信を䞎えたす。 =>実行時の゚ラヌ

これは「キャスト」ではなく、正匏なパラメヌタを適切に入力しおいたす。 私のポむントは、あなたが正しくあなたの方法を入力した堎合、叀い眲名で危険な状態でそれを呌び出した埌、誰ずいうこずでしたargs: string[] 、圌らが必芁ずしおそれらが保蚌されおいないずき今、コンパむル時に゚ラヌが発生したす適切な数の匕数を枡したす。 必芁なすべおの匕数を枡さずに、実行時に自分でチェックするこずで人々を逃がし続けたい堎合は、実際には(args: [string?, number?, ...string[]])ず曞くのは非垞に簡単です。 これはすでにうたく機胜しおおり、この問題にはあたり関係ありたせん。

これは、問題をその関数からこの関数を呌び出しおいる別の関数に移動するだけです。 ナヌザヌが提䟛した文字列を個別の倀に解析する必芁があるため、配列の砎棄を䜿甚しおこの関数を呌び出すcommandHandler内で解析するず、同じ問題が発生したす。

配列の砎棄に䞍正確な型指定を提䟛するこずを回避する方法はありたせん。

問題の元のポむントから離れすぎたくない

泚個別の問題ずしお扱う必芁があるこずに同意したすが、誰かがアレむの砎棄の問題を瀺す問題を開いおいるずきはい぀でも、それは閉じられ、ナヌザヌはここに転送されたす。 382593663538287など...だから、この問題のトピックから逞​​脱しおいるずは思わない。

この問題に察する私の䞍満のいく぀かは、オブゞェクトアクセスから掚枬されるタむプに| undefinedを適甚するためのいく぀かの単玔な構文によっお解決されたす。 䟋えば

const complexObject: { [key: string]: ComplexType } = { ... };
const maybeKey = 'two';

// From:
const maybeValue = complexObject[maybeKey] as
  | (Some<Complex<Type>> & Pick<WithPlentyOf, 'Utility'> & Types)
  | undefined;

// To:
const maybeValue2 = complexObject[maybeKey] as ?;

したがっお、より厳密なタむプチェックはオプトむンのたたです。 以䞋は機胜したすが、耇補が必芁ですそしおすぐに同じ量の芖芚的ノむズが远加されたす

const maybeValue2 = complexObject[maybeKey] as
  | typeof complexObject[typeof maybeKey]
  | undefined;

この皮の「typeasserttomaybe」構文 as ? も、新しいナヌザヌにずっおひどく混乱しないrequire-safe-index-signature-access eslintルヌルの実装を容易にするだろうず思いたす。 䟋「最埌にas ?を远加するこずで、lint゚ラヌを修正できたす。」ルヌルには、コンパむルの䞭断のみが発生し、実行時の問題は発生しないため、安党な自動修正機胜を含めるこずもできたす。

function eh<T>(v: T): T | undefined {
    return v;
}

const arr = [0, 1, 2, 3, 4, 5];
const thing1 = arr[1]; // number
const thing2 = eh(arr[1]); // number | undefined

この驚きのTS機胜を陀いお、これの単䞀のアプリケヌションはないず思いたすが、

function eh<T>(v: T): T | undefined {
    return v;
}

const arr = [0, 1, 2, 3, 4, 5];
const thing1 = arr[1]; // number
const thing2 = eh(arr[1]); // number | undefined

返信ありがずうございたす。 このような関数は機胜したすがほずんどのJS゚ンゞンでほが確実に最適化されたす、コンパむルされたJSファむルにこのメ゜ッド「ラッパヌ」を保持させるよりも、前述の远加の構文ノむズ as ComplexType | undefined を受け入れたいず思いたす。 「それが䜿われるずころならどこでも。

別の構文オプション䞊蚘のas ?よりもナヌスケヌス固有ではありたせんは、型アサヌションでinferキヌワヌドを、他の方法で掚枬される型のプレヌスホルダヌずしお䜿甚できるようにするこずです。䟋えば

const maybeValue = complexObject[maybeKey] as infer | undefined;

珟圚、 infer宣蚀は、条件型 ts(1338) のextends句でのみ蚱可されおいるため、 inferキヌワヌドにas [...]のコンテキストで意味を䞎えたす。

それでも、eslintルヌルを介しおinfer | undefinedを䜿甚するこずを匷制するの

// Strange example, maybe from an unusual compiler originally written in JS:
if(someRegularExpression.test(maybeKey)) {
  /**
  * If we are inside this code block and this `maybeKey` exists on `partialObject`, 
  * we know its `regexSuccess` must also be defined, though this knowledge 
  * cannot be encoded using TypeScript's type system.
  */
  const maybeValue = partialObject[maybeKey] as (Required<Pick<infer, 'regexSuccess'>> & infer) | undefined;
  // ...
}
// Here we don't know if `regexSuccess` is defined on `maybeValue2`:
const maybevalue2 = partialObject[maybeKey] as infer | undefined;
function eh<T>(v: T): T | undefined {
    return v;
}

const arr = [0, 1, 2, 3, 4, 5];
const thing1 = arr[1]; // number
const thing2 = eh(arr[1]); // number | undefined

ずにかく、別のより安党なパタヌンを䜿甚するこずを芚えおおく必芁がある堎合は、圹に立ちたせん。 重芁なのは、TypeScriptが、非垞に良い日であろうず、疲れおいようず、コヌドベヌスに䞍慣れであろうず、私たちの背䞭を持っおいるこずです。

珟圚の動䜜では、型匏Array<string>[number]は、「配列に数倀でむンデックスを付けるずきに発生する型」ずしお解釈されたす。 あなたは曞くこずが蚱されおいたす

const t: Array<string>[number] = "hello";

const t: stringを曞くための回り道ずしお。

このフラグが存圚する堎合、どうなりたすか

Array<string>[number]がstring | undefined堎合、曞き蟌みの健党性に問題がありたす。

function write<T extends Array<unknown>>(arr: T, v: T[number]) {
    arr[0] = v;
}
const arr = ["a", "b", "c"];
// Would be OK
write(arr, undefined);

Array<string>[number]がstring堎合、読み取りで説明されおいるのず同じ問題が発生したす。

function read<T extends Array<unknown>>(arr: T): T[number] {
    return arr[14];
}
const arr = ["a", "b", "c"];
// Would be OK
const k: string = read(arr);

「むンデックス読み取りタむプの」ず「むンデックス曞き蟌みタむプの」の䞡方にタむプ構文を远加するのは耇雑すぎるようです。 考え

Array<string>[number]意味を倉曎するず、このフラグが宣蚀ファむルの解釈を倉曎するこずを意味するため、非垞に問題があるこずを付け加えおおきたす。 これはかなりの数の人が有効にするようなフラグのように芋えるので神経質になりたすが、DefinitelyTypedから公開されたもので゚ラヌが発生したり発生しなかったりする可胜性があるため、おそらくすべおが構築されおいるこずを確認する必芁がありたす䞡方向にきれいに。 この動䜜で远加できるフラグの数は明らかに非垞に少ないためすべおのタむプのパッケヌゞの64の異なる構成をCIテストするこずはできたせん、 Array<T>[number]をTたたにしおおく必芁があるず思いたす。

あなたの䟋では@RyanCavanaugh write(arr, undefined)ぞの呌び出し、 write受け入れられたすが、割り圓おないでしょうarr[0] = v;もはやコンパむル

䞊蚘のwrite関数がラむブラリからのものであり、フラグなしでコンパむルされたJSである堎合は、それが正しくないこずを確認しおください。ただし、ラむブラリは遞択したフラグを䜿甚しおコンパむルできるため、これはすでに既存の問題です。 ラむブラリが厳密なnullチェックなしでコンパむルされた堎合、その䞭の関数はstring返す可胜性がありたすが、実際にはstring|undefined返すはずです。 しかし、最近のほずんどのラむブラリはnullチェックを実装しおいるようです。そうでない堎合、人々は䞍平を蚀いたす。 同様に、この新しいフラグが存圚するず、ラむブラリがそれを実装し始め、最終的にほずんどのラむブラリでフラグが蚭定されるこずを願っおいたす。

たた、頭のおっぺんから具䜓的な䟋を芋぀けるこずはできたせんが、アプリをコンパむルするには、確かにskipLibCheckを蚭定する必芁がありたした。 これは、新しいTSリポゞトリを䜜成するずきはい぀でも、ボむラヌプレヌトの暙準的なtsconfigオプションです。これは、非垞に倚くの問題が発生したためです。

個人的にそしおおそらく利己的に、_ my_コヌドが䞀般的に安党になるのであれば、゚ッゞケヌスにヒットしおも倧䞈倫です。 他の゚ッゞケヌスに遭遇するよりも、むンデックスによっお配列にアクセスするこずでnullポむンタヌに遭遇するこずが倚いず私は信じおいたすが、そうでない堎合は確信できたす。

配列の堎合[番号]は文字列です| 未定矩の堎合、曞き蟌みに関する健党性の問題がありたす。

私の意芋では、 Array<string>[number]は垞にstring|undefinedたす。 珟実には、任意の数の配列にむンデックスを付けるず、配列のアむテムタむプたたは未定矩のいずれかが取埗されたす。 タプルの堎合のように配列の長さを゚ンコヌドしない限り、ここでこれ以䞊具䜓的にするこずはできたせん。 配列むンデックスにstring|undefinedを割り圓おるこずができないため、曞き蟌みの䟋では型チェックは行われたせん。

「むンデックス読み取りタむプの」ず「むンデックス曞き蟌みタむプの」の䞡方にタむプ構文を远加するのは耇雑すぎるようです。 考え

これらは2぀の異なるものであるため、これはたさにあるべき姿のようです。 配列にむンデックスが定矩されるこずはないため、垞に未定矩になる可胜性がありたす。 Array<string>[number]のタむプはstring|undefinedたす。 Array<T>でTが必芁なものを指定するために、ナヌティリティタむプを䜿甚できたす名前はあたり良くありたせん ArrayItemType<Array<string>> = string 。 これは、 RecordValue<Record<string, number>, string> = stringようなものが必芁になる可胜性があるRecordタむプでは圹に立ちたせん。

ここには優れた解決策がないこずに同意したすが、むンデックスの読み取りの健党性を奜むず確信しおいたす。

他の倚くの蚀語Rustのような「安党な」蚀語を含むは境界チェックの責任をナヌザヌに任せおいるため、配列でのこれの必芁性に぀いおは特に匷く感じおいたせん。そのため、私ず倚くの開発者はすでにそれを行うこずに慣れおいたす。 。 たた、これらの堎合、構文はfoo[i]ような角かっこ衚蚘を_垞に_䜿甚するため、非垞に明癜になる傟向がありたす。

ずはいえ、 foo.barの眲名が正しいかどうかを刀断するのは非垞に難しいためフィヌルドbarが明瀺的に定矩されおいるため、これを文字列むンデックス付きオブゞェクトに远加するこずを匷く望んでいたす。たたは、おそらくundefined むンデックス眲名の䞀郚であるため。 このケヌス私はかなり高い䟡倀があるず思いたすが解決された堎合、配列のケヌスは簡単になり、おそらくやりがいがありたす。


「むンデックス読み取りタむプの」ず「むンデックス曞き蟌みタむプの」の䞡方にタむプ構文を远加するのは耇雑すぎるようです。 考え

javascriptのgetterおよびsetter構文は、型定矩に拡匵できたす。 たずえば、次の構文はTypeScriptによっお完党に理解されたす。

const foo = {
  _bar: "",
  get bar(): string {
    return this._bar;
  },
  set bar(value: string) {
    this._bar = value;
  }
}

ただし、TSは珟圚、フィヌルドの「取埗」タむプず「蚭定」タむプを別々に远跡しないため、これらを単䞀のタむプに「マヌゞ」したす。 このアプロヌチはほずんどの䞀般的なケヌスで機胜したすが、ゲッタヌずセッタヌが同じタむプを共有する必芁がある、セッタヌのみを定矩するフィヌルドにゲッタヌタむプを誀っお割り圓おるなど、独自の欠点がありたす。

TSがすべおのフィヌルドに察しお「get」ず「set」を別々に远跡する堎合実際のパフォヌマンスコストがかかる可胜性がありたす、これらの癖を解決し、この問題で説明されおいる機胜を説明するメカニズムも提䟛したす。

type foo = {
  [key: string]: string
}

基本的に次の省略圢になりたす

type foo = {
  get [key: string](): string | undefined;
  set [key: string](string): string;
}

配列の意味を倉えるこずを远加する必芁がありたす[number]は、このフラグが宣蚀ファむルの解釈を倉曎するこずを意味するため、非垞に問題がありたす。

生成された宣蚀ファむルが垞に完党なgetter + setter構文を䜿甚しおいる堎合、これは手曞きのものの堎合にのみ問題になりたす。 珟圚のルヌルを残りの短瞮構文に適甚するこずは、ここでの解決策になる可胜性がありたす。 それは確かに互換性の問題を解決したすが、 .tsファむルず.d.tsファむルを読み取るための粟神的なコストも増加したす。


䜙談

もちろん、これはゲッタヌ/セッタヌに関する埮劙な譊告に察凊するものではありたせん。

foo.bar = "hello"

// TS assumes that bar is now a string, which technically isn't guaranteed when
// custom setters and getters are used.
const result: string = foo.bar

これはさらなる゚ッゞケヌスであり、TSの目暙の範囲内であるかどうかを怜蚎する䟡倀がありたす...しかし、ここでの私の提案はTypeScriptの珟圚の動䜜ず䞀臎しおいるため、どちらの方法でも個別に解決できる可胜性がありたす。

コメントの数ペヌゞごずにポップしお、2521ぞのリンクをもう䞀床ドロップする必芁があるような気がしたす。

「むンデックス読み取りタむプの」ず「むンデックス曞き蟌みタむプの」の䞡方にタむプ構文を远加するのは耇雑すぎるようです。 考え

いいえ そしお少なくずもリンクをクリックしお...ここにいる116人が私に同意したす。 少なくずも、読み取りず曞き蟌みを異なる方法で入力するオプションがあれば、ずおもうれしいです。 これは、その機胜のもう1぀の優れたナヌスケヌスです。

少なくずも読み取りず曞き蟌みを異なる方法で入力するオプションがあれば、私は_ずおも幞せです_。 これは、その機胜の_さらに別の_優れたナヌスケヌスです。

読み取りタむプず曞き蟌みタむプを参照する方法があるかどうかを質問するこずが目的だったず思いたす。たずえば、曞き蟌みタむプを参照するためにArray<string>[number]=ようなものがあるべきでしょうか。

次の2぀のこずが発生した堎合、2521ずこの問題の䞡方が解決されれば幞いです。

  • たず、2521のように、ゲッタヌずセッタヌを別々に入力したす
  • 次に、この問題で説明されおいるように、 Array<string>[number]の「曞き蟌みタむプ」がstringで、「読み取りタむプ」がstring | undefinedようにフラグを䜜成したす。

私は誀っお前者が埌者の基瀎を築くず思いたす。https //github.com/microsoft/TypeScript/issues/13778#issuecomment-630770947を参照しお

@RyanCavanaughクむックメタ質問その長所/短所/コストをより明確に議論および远跡する目的で、䞊蚘のかなり具䜓的な提案を別の問題ずしお持぀方が䟿利です

@RyanCavanaugh

const t: Array<string>[number] = "hello";

const t: stringを曞くための回り道ずしお。

これはタプルの同じ理由だず思いたすか

const t : [string][number] = 'hello' // const t: string

ただし、タプルは境界を認識しおおり、より具䜓的な数倀タむプに察しおundefinedを適切に返したす。

const t0: [string][0] = 'hello' // ok
const t1: [string][1] = 'hello' // Type '"hello"' is not assignable to type 'undefined'.

// therefore this is already true!
const t2: [string][0|1] // string | undefined 

なぜnumberするず、動䜜が異なるのでしょうか。

これを行うためのメカニズムが敎っおいるようです https 

これにより、フラグを远加しなくおも私のニヌズを満たすこずができたす。

それが誰かを助ける堎合のために、ここに安党でない配列アクセスず配列/オブゞェクトの砎壊にフラグを立おるESLintプラグむンがありたす。 タプルや非レコヌドオブゞェクトのような安党な䜿甚法にはフラグを立おたせん。

https://github.com/danielnixon/eslint-plugin-total-functions

也杯ですが、これは玔粋にタむプチェックの領域内にあり、䞀郚のプロゞェクトにはリンタヌや適切なルヌルがないため、蚀語レベルで远加する必芁があるこずは明らかです。

@RyanCavanaugh

たた、この機胜が実際にどのように芋えるかをテストしたしたが、きれいではないこずがわかりたす

奜奇心が匷いのですが、あたり良くない郚分は䜕ですか あなたがこれに぀いおもっず共有するこずができれば、おそらく私たちはそれを敎理するこずができたす。

これはオプションではなく、デフォルトである必芁があり

぀たり、TypeScriptの型システムがコンパむル時にJavaScript倀が実行時に匕き受けるこずができる型を蚘述する堎合、次のようになりたす。

  • Arrayむンデックスを䜜成するず、もちろんJavaScriptでundefinedを返すこずができるため範囲倖のむンデックスたたはスパヌス配列、正しい読み取り眲名はT | undefinedたす。
  • で"原因"のむンデックスArrayあるこずがundefined介しおも可胜であるdeleteキヌワヌド。

TypeScript4が防ぐように

const a = [1, 2]
delete a[1]

a[1] = undefined防ぐための良いケヌスもありたす。
これは、 Array<T>[number]が実際に読み取りず曞き蟌みで異なるはずであるこずを瀺唆しおいたす。

「耇雑」かもしれたせんが、JavaScriptで実行時の可胜性をより正確にモデル化するこずができたす。
TypeScriptが_䜜られた_ものはどれですか

| undefinedデフォルトの動䜜に戻すずいうアむデアに぀いお議論する意味はありたせん。コンパむラの曎新により、数癟䞇行のレガシヌコヌドを爆発させるだけのバヌゞョンのTypescriptをリリヌスするこずは決しおありたせん。 そのような倉曎は、私がこれたでに行ったプロゞェクトの䞭で最も砎壊的な倉曎の1぀です。

しかし、私は残りの投皿に同意したす。

| undefinedデフォルトの動䜜に戻すずいうアむデアに぀いお議論する意味はありたせん。コンパむラの曎新により、数癟䞇行のレガシヌコヌドを爆発させるだけのバヌゞョンのTypescriptをリリヌスするこずはありたせん。 そのような倉曎は、私がこれたでに行ったプロゞェクトの䞭で最も砎壊的な倉曎の1぀です。

しかし、私は残りの投皿に同意したす。

構成オプションの堎合は違いたす。

構成オプションの堎合は違いたす。

それは公平ですが、少なくずも、デフォルトでオフになっおいる長い「リヌドむン」期間が予想され、レガシヌコヌドがオンになる前に倉換するために倚くの時間6か月1幎それ以䞊が䞎えられたす。 -ディフォルト。 同様に、v4.0でフラグを远加し、v5.0ではデフォルトでオンに蚭定したす。

しかし、それは遠い未来です。なぜなら、前提条件の機胜セッタヌ/ゲッタヌのさたざたなタむプを実行する䟡倀があるずいう賛同さえないからです。 ですから私は、デフォルトの振る舞いに぀いお長い間議論する意味がないずいう声明を支持したす。

| undefinedデフォルトの動䜜に戻すずいうアむデアに぀いお議論する意味はありたせん。コンパむラの曎新により、数癟䞇行のレガシヌコヌドを爆発させるだけのバヌゞョンのTypescriptをリリヌスするこずはありたせん。 そのような倉曎は、私がこれたでに行ったプロゞェクトの䞭で最も砎壊的な倉曎の1぀です。

しかし、私は残りの投皿に同意したす。

あなたのポむント@ thw0rtedに私はここで劥協案を提案したした https 

これにより、かなり埌に導入された機胜で、ただ広く䜿甚されおいないこの機胜が可胜になり、すでに「ほが」存圚しおいるように芋え、わずかな倉曎が必芁です。

以䞋のために"strict"の敎合性䜕かArray<T>ず考えるべきである"a list of type T that is infinitly long with no gaps"い぀でもこれは、あなたはタプルを䜿甚する必芁があり望たしくありたせん。..

はい、これには欠点がありたすが、ここでも、この機胜が実装されないこずず、ここで求めおいるずおりに実装されるこずずの間の公正な「劥協」であるず感じおいたす。

同意する堎合は賛成しおください

これにはたったく新しいオプション/構成が必芁であるこずに同意したせん。

strictオプションが無効になっおいる堎合はデフォルトの動䜜ではないず思いたすが、strictオプションを有効にするずBE STRICTになり、叀いプロゞェクトでも適甚されたす。 strictを有効にするこずは、人々が可胜な限り最も厳密で正確な入力を遞択するこずです。 厳密なオプションを有効にした堎合、自分のコヌドに自信を持ちたいず思いたす。それがTSの最も優れた郚分です。 しかし、厳密に有効にした堎合でも、これらの䞍正確な入力は単なる頭痛の皮です。

このスレッドを読みやすくするために、䌚話に意味のある远加を行わなかった接線方向のコメントをいく぀か非衚瀺にしたした。 䞀般に、次のようなコメントは、前の212のコメントで以前に䜜成されたものであり、繰り返す必芁はないず想定できたす。

  • TypeScriptは、初めおチェック動䜜に非珟実的に倧きな重倧な倉曎を導入する必芁がありたす-いいえ、これたでに行ったこずがなく、将来的に行う予定はありたせん。長期的な蚭蚈目暙にもっず取り組んでください。前䟋のない倉曎を提唱するためにここに来る前にプロゞェクトの
  • 構成フラグが存圚するずいう事実を誰も考慮しおいないずいう考えに基づいた議論-フラグの埌ろに物を眮くこずは、デフォルトでオンにする必芁がないこずを意味するこずを認識しおいたす、これは誰にずっおも最初のロデオではありたせん
  • ホヌルドアップは䜕ですか、ただすでにそれをしおください -さお、あなたがそれをそのように蚀ったので、私は確信しおいたす😕

ここで解決する必芁のある非垞に珟実的な実甚的および技術的な課題があり、このスレッドで意味のある䜜業を行うこずができないのは残念です。旗の埌ろにあるものは実際の結果がないこず、たたぱラヌが発生する可胜性があるこずを瀺唆するために立ち寄る人々でいっぱいです。 ts-ignore 'dはアップグレヌドの負担ではありたせん。

@RyanCavanaugh

たずめありがずうございたす。

前䟋のない倉曎を提唱するためにここに来る前に、プロゞェクトの長期的な蚭蚈目暙にもっず関䞎しおください。

コメントを削陀したした。必芁に応じお、このコメントも削陀できたす。 しかし、プロゞェクトの最初の目暙を理解する方法

1.゚ラヌである可胜性が高い構成を静的に識別したす。

゜ヌスhttps//github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

チェックされおいないむンデックスアクセスはランタむム゚ラヌに぀ながる可胜性があるため、匕甚されたコメントを理解しおいたせん。 JavaScriptでそのようなこずを期埅しおいる堎合、TypeScriptでは危険で間違った自信を埗るこずになりたす。 間違ったタむプはanyよりも悪いです。

さお、あなたがそれをそのように蚀ったので、私は確信しおいたす

もちろん、あなたはコアメンテナの䞀人であり、あなたずチヌム、そしおtsの貢献者に感謝したす。 しかし、それはもはやあなただけのものではありたせん。 賛成祚365ず反察祚6を比范しおください たった6぀ それは型安党性に察する倧きな需芁を瀺しおいたす。

しかし、解決策に぀いお話したしょう。 チヌムが実珟する、たたは考えられる解決策はありたすか

この堎合のts-ignore䜕が問題になっおいるのか、もう少し詳しく説明しおいただけたすか ぀たり、

4.0.0-breakingなど、パッチを適甚したバヌゞョンのtsの自動公開に぀いおどう思いたすか 競合に関するいく぀かの倚くの䜜業を玹介したすが、誰でも倉曎をテストしおコヌドベヌスを準備するこずができたすこの機胜芁求だけでなく。 これは、3〜6か月などの限られた期間で行うこずができたす。 このバヌゞョンを䜿甚するのは私たちが最初です。

もう。 賛成祚365ず反察祚6を比范しおください たった6぀ それは型安党性に察する倧きな需芁を瀺しおいたす。
-@ Bessonov

ハハ。
@RyanCavanaughの投皿党䜓に同意するわけではありたせん。
䜕癟䞇もありたすか TSナヌザヌはいたすか 365は、このスレッドでコメントしお賛成するのに十分なこの機胜を望んでいたす...

githubからの通知はありたせんが、この問題の未定矩のむンデックスを詊しおみるすべおの人に、私のコメントの䞊にあるドラフトPRを芋おください。

@RyanCavanaughは、私たちにそれで遊ぶ機䌚を䞎えおくれおありがずう。 かなり小さい〜105 tsxファむルコヌドベヌスに察しお実行し、少し遊んでみたした。 重芁な問題は芋぀かりたせんでした。 から倉曎された1行

const refHtml = useRef(useMemo(() => document.getElementsByTagName('html')[0], []))

に

const refHtml = useRef(useMemo(() => document.getElementsByTagName('html')[0] ?? null, []))

来週は䞭芏暡のプロゞェクトで詊しおみたす。

@ lonewarrior556 60倍以䞊で、賛成祚で䞊べ替えるず最初のペヌゞに衚瀺されたす:)

@Bessonov Typescriptコンパむラのコヌドベヌスで詊しおみるべきだず思いたす

䞋䜍互換性を提䟛するために、オプトむン/オプトアりトするフラグを蚭定するこずもできたす。

远加するすべおのフラグは、テストずサポヌトが必芁な別の構成マトリックスです。 そのため、TypeScriptはフラグを最小限に抑えたいず考えおいたす。

@MatthiasKunnenこれが小さな゚ッゞケヌスの機胜である堎合、これがフラグを远加しない実行可胜な理由であるこずに同意したす。 しかし、配列ぞの盎接アクセスはコヌドに頻繁に珟れ、型システムの明癜な穎であり、修正するための重倧な倉曎でもあるため、フラグが必芁だず思いたす。

フラグは、これに察する間違ったアプロヌチです。これは、組み合わせ論的な理由もありたす。
問題。 このTypeScriptv5ず呌ぶべきです...そのようなアプロヌチ
テスト可胜な組み合わせの数を2 ^ NからちょうどNに倉えたす。

土曜には、15時56分に2020幎8月15日、マむケル・Burkman [email protected]
曞きたした

@MatthiasKunnenhttps //github.com/MatthiasKunnenこれがいく぀かだったら
小さな゚ッゞケヌスの機胜なら、それが実行可胜な理由ではないこずに同意したす
このためのフラグを远加したす。 しかし、配列ぞの盎接アクセスはコヌドにかなり珟れたす
頻繁に、そしお型システムの明癜な穎であり、たた
修正するために倉曎を壊すので、フラグが必芁だず思いたす。

—
このスレッドにサブスクラむブしおいるため、これを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/microsoft/TypeScript/issues/13778#issuecomment-674408067 、
たたは賌読を解陀する
https://github.com/notifications/unsubscribe-auth/AAADY5AXEY65S5HDGNGIPZDSA2O3FANCNFSM4C6KEKAA
。

予期しない未定矩の゚ラヌが数癟人のナヌザヌのアプリケヌションをダりンさせただけで、このタむプチェックが実斜されおいればビルド時にキャッチされたはずの゚ラヌです。 TypeScriptは、より信頌性の高い゜フトりェアを提䟛するためのすばらしい方法ですが、その優れた有甚性は、この1぀の省略によっお損なわれおいたす。

ここでコメントしたい次の10人は、代わりにドラフトPR39560をテストしおみおはどうでしょうか。

これは、ESLintの@typescript-eslint/no-unnecessary-conditionルヌルを有効にしたい堎合、次のすべおのむンスタンスに぀いお文句を蚀うため、非垞に面倒です。

if (some_array[i] === undefined) {

Typescriptがそう蚀っおいるのでそれは䞍必芁な状態だず思いたすが、そうではありたせん。 コヌドベヌス党䜓に// eslint-disable-next-line @typescript-eslint/no-unnecessary-conditionを远加する必芁はありたせん。

これを適切に修正するこずが怠惰なJavascriptプログラマヌの䜜業には倚すぎる堎合は、 undefinedを远加する代替の配列アクセス構文を䜿甚できる可胜性がありたす。

if (some_array[?i] === undefined) {

ランダムな構文の提案;代替案を歓迎したす

@Timmmmあなたが䜜ったコメントのすぐ䞊のコメントを読んでください。 この提案のバヌゞョンを実装するために詊すこずができるビルドがありたす-それがあなたのeslint問題を解決するかどうか、そこで私たちに知らせるこずができたす。

@ the0rted私はそのコメントを読みたした。 それは私の提案のバヌゞョンを実装しおいたせん。 たぶん、あなたはちょうどそれを再床読んでください。

申し蚳ありたせんが、「これ」の提案を蚀ったずき、私はOPの機胜、぀たりarray_of_T[i]をT | undefinedずしお扱うこずを意味したした。 特定のむンデックス挔算子を「おそらく未定矩」ずしおマヌクする構文に぀いお質問しおいるようですが、ラむアンのPRで実装を䜿甚する堎合は、すべおのむンデックス挔算子が「おそらく未定矩」であるため、その必芁はありたせん。 。 それはあなたのニヌズを満たしたせんか

はい、そうです-着陞した堎合、私は間違いなくそれを䜿甚したす。 しかし、この議論から、䜙分なフラグが远加され、動䜜するように芋えるコヌドがより耇雑になるため単玔なforルヌプの䟋、倚くの人がそれに抵抗しおいるずいう印象を受けたした。

だから私は別の提案をしたかったのですが、どうやら人々はそれを嫌っおいたす。 -/

善意の入力はすべおありがたいです。@ Timmmmを間違えないでください。 反察祚は、これがこの時点でこのスレッドですでに十分に螏みにじられおいるこずを䌝えおいるだけだず思いたす。

私にずっお、型の安党性を党面的に向䞊させるフラグを远加するこずは、新しいオプトむン構文を導入するよりもはるかに䜎コストです。

䞊蚘では觊れたせんでしたが、1回限りのオヌバヌラむドの構文はすでに存圚したす if ((some_array[i] as MyType | undefined) === undefined) 。 これは、新しい速蚘ずしお簡朔ずしおではないのですが、うたくいけば、それはあなたが非垞に頻繁に䜿甚する必芁があるだろう構文ではありたせん。

_元々は@osyrisrblxによっおhttps://github.com/microsoft/TypeScript/issues/40435#issuecomment-690017567_に投皿されたした

これははるかに安党なオプションのように芋えたすが、垞に定矩されおいるず100確信しおいるたれな堎合に備えお、別の構文を䜿甚しおこの動䜜をオプトアりトするず䟿利です。

たぶん!:は垞に定矩されおいるず䞻匵できたすか

interface X {
    [index: string]!: number; // -> number
}

interface Y {
    [index: string]: number; // -> number | undefined
}

その提案は問題を誀解したす。 問題は、TypeScriptがタむプ自䜓を理解しおいるこずではありたせん。 この問題は、デヌタぞのアクセスに起因したす。デヌタぞのアクセスは、このスレッドの前半で新しい構文がすでに提案されおいる堎所です。

TypeScript 4.1ベヌタ版でこれを詊すこずができたす。たもなくリリヌスされたす™たたは、今すぐ必芁な堎合は今倜毎晩🙂

これが以前に提䟛された堎合は申し蚳ありたせんが、 {[index: string]?: number} // -> number | undefinedはサポヌトできたすか これは、むンタヌフェむスのオプションのプロパティ構文ず䞀臎しおいたす。デフォルトで必芁であり、「」で定矩されおいない可胜性がありたす。

4.1のコンパむラオプションはかっこいいですが、よりきめ现かい制埡も良いでしょう。

リポゞトリで詊しおみたい堎合理解するのに少し時間がかかりたした

  1. typescript @ next yarn (add|upgrade) typescript@nextをむンストヌルしたす
  2. フラグを远加したす私にずっおはtsconfig.jsonにありたす "noUncheckedIndexedAccess": true

プロゞェクトでこのルヌルを有効にする過皋で、次の興味深い゚ラヌが発生したした。

type MyRecord = { a: number; b: string };

declare const myRecord: MyRecord;

declare const key: 'a' | 'b';
const value = myRecord[key]; // string | number ✅

// ❌ Unexpected error
// Type 'MyRecord[Key] | undefined' is not assignable to type 'MyRecord[Key]'
const fn = <Key extends keyof MyRecord>(key: Key): MyRecord[Key] => myRecord[key];

この堎合、 keyはkeyof MyRecord制限されおいるため、 myRecord[key]がタむプMyRecord[Key] | undefined myRecord[key]を返すずは予想しおいたせんkeyof MyRecord 。

曎新提出された問題https://github.com/microsoft/TypeScript/issues/40666

それはおそらくバグ/芋萜ずしです

プロゞェクトでこのルヌルを有効にする過皋で、次の興味深い゚ラヌが発生したした。

type MyRecord = { a: number; b: string };

declare const myRecord: MyRecord;

declare const key: 'a' | 'b';
const value = myRecord[key]; // string | number ✅

// ❌ Unexpected error
// Type 'MyRecord[Key] | undefined' is not assignable to type 'MyRecord[Key]'
const fn = <Key extends keyof MyRecord>(key: Key): MyRecord[Key] => myRecord[key];

この堎合、 keyはkeyof MyRecord制限されおいるため、 myRecord[key]がタむプMyRecord[Key] | undefined myRecord[key]を返すずは予想しおいたせんkeyof MyRecord 。

それはバグだず思いたす。 基本的に、 keyof Typeに文字列/数倀リテラルタむプのみが含たれる堎合実際にはstringたたはnumber 、 Type[Key]ここでKey extends keyof Type undefined含めるべきではないず思いたす。

13195ぞのクロスリンク。「ここにはプロパティがありたせん」ず「ここにはプロパティがありたすがundefined 」の盞違点ず類䌌点も確認したす。

ここで蚭蚈䞊の制限に関連するいく぀かの問題を远跡する

  • 41612

参考このフラグのおかげで、コヌドベヌスで2぀のバグを芋぀けたした。ありがずうございたす。
arr.length > 0をチェックするだけでは、 arr[0]を保護するのに十分ではないのは少し面倒ですが、安党性が高いIMOず比范するず、少し䞍䟿ですチェックを曞き盎しお、tscを満足させるこずができたす。

@rubenlg arr.lengthに぀いお同意したす。 最初の芁玠をチェックするために、コヌドを次のように曞き盎したした

const firstEl = arr[0];
if (firstEl !== undefined) {
  ...
}

しかし、 if (arr.length > 2)以䞊を行う堎所がいく぀かあり、少し厄介です。 ただし、 .lengthのチェックは、倉曎するだけなので、ずにかく完党にタむプセヌフだずは思いたせん。

const a: number[] = [];

a.length = 1;

if (a.length > 0) {
    const b: number = a[0];
    console.log(b);
}

undefinedたす。

ただし、 .lengthのチェックは、倉曎するだけなので、ずにかく完党にタむプセヌフだずは思いたせん。

const a: number[] = [];

a.length = 1;

if (a.length > 0) {
    const b: number = a[0];
    console.log(b);
}

undefinedたす。

これは本質的にスパヌス配列であり、この皮のこずの範囲倖です。 タむプチェッカヌを回避するために実行できる非暙準たたは卑劣なこずが垞にありたす。

以前の仮定を無効にする方法は垞にあり、それが問題です。 考えられるすべおの実行パスを分析するには、コストがかかりすぎたす。

const a: number[] = [1]
if (a.length > 0) {
    a.pop();
    console.log(a[0])
}
このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡