// code snippet
function valueOrDefault(a?: string) {
return a || "the default";
}
dengan konfigurasi tslint.json
:
{
"defaultSeverity": "error",
"extends": [
"tslint:all"
]
}
Mendapatkan laporan dari 2 kesalahan:
strict-boolean-expressions This type is not allowed in the operand for the '||' operator because it could be undefined. Only booleans are allowed.
strict-boolean-expressions This type is not allowed in the operand for the '||' operator because it is always truthy. Only booleans are allowed.
Tidak ada kesalahan yang dilaporkan. Saya menggunakan operator ||
logis untuk memberikan nilai default untuk parameter (saya tahu saya bisa menggunakan deklarasi default parameter fungsi, cuplikan hanya untuk menggambarkan masalah umum). Tidak ada boolean
dimainkan di mana pun: baik input maupun output dari ekspresi.
Pikiran? Doa? Saran di mana/bagaimana memulainya?
@marcind dapatkah Anda memberikan contoh bagaimana seharusnya berperilaku berbeda dari pergantian aturan?
Maaf, bagian mana pengajuan awal saya yang tidak jelas?
Saya kira maksud saya adalah bahwa aturan ini hanya boleh berjalan dalam "konteks boolean", saya dapat memikirkan dua kasus:
if
, while
, atau for
boolean
.Aturan tidak boleh berjalan ketika saya mencoba memberikan nilai default atau evaluasi hubung singkat
const a: string = potentiallyUndefinedString || "the default";
const a: string | undefined = potentiallyUndefinedObject && potentiallyUndefinedObject.getString()
@marcind contoh dari posting terakhir Anda akan berfungsi jika Anda menggunakan opsi "allow-undefined-union"
.
Bagian lain dari permintaan Anda harus berupa aturan terpisah bernama strict-boolean-conditions
yang hanya memeriksa if
, for
, while
, do ... while
dan kondisional ekspresi ( x ? y : z
).
Saya bisa membayangkan itu hanya akan memeriksa jenis seluruh kondisi dan bukan konstituennya:
function foo(a: boolean, b?: boolean) {
if (b || a) {} // passes, result is always boolean
if (b && a) {} // fails, result is boolean | undefined
if (a || b) {} // fails, result is boolean | undefined
if (a || !!b) {} // passes
}
Mungkin ini bisa menjadi pilihan untuk aturan yang ada daripada aturan baru...
Menurut pendapat saya, strict-boolean-expressions
seharusnya hanya memeriksa operan kiri &&
dan ||
. Operator tersebut (pada dasarnya) adalah gula untuk ternaries: a && b
sama dengan a ? b : a
, dan a || b
sama dengan a ? a : b
. Ketika Anda memikirkannya dalam istilah itu, mengabaikan RHS sangat masuk akal, dan itu akan membawa perilaku untuk operator hubung singkat sejalan dengan perilaku untuk ternaries.
Kemudian , jika semuanya ada di dalam if/for/while, strict-boolean-conditions
bisa ikut bermain dan memeriksa ekspresi keseluruhan . Saya pikir ini akan mencakup semua kasus yang berguna, dan saya dapat mengaktifkan kembali aturan ini.
Kode yang menandai ini sebagai masalah bagi saya adalah pola React umum yang terdokumentasi ini:
function Foo(props: { showToggle: boolean }) {
return <div>{props.showToggle && <Toggle />}</div>;
}
ERROR: 2:36 strict-boolean-expressions This type is not allowed in the operand for the '&&' operator because it is always truthy. Allowed types are boolean, null-union, undefined-union, string, or number.
@ajafff Kodenya tidak lulus linter untuk saya, bahkan dengan semua opsi aturan diaktifkan, karena RHS konstan:
export function valueOrDefault(a?: string) {
return a || "the default";
}
"strict-boolean-expressions": [true, "allow-null-union", "allow-undefined-union", "allow-string", "allow-number", "allow-mix"]
ERROR: 2:15 strict-boolean-expressions This type is not allowed in the operand for the '||' operator because it is always truthy. Allowed types are boolean, null-union, undefined-union, string, or number.
Maksud dari ekspresi itu adalah persyaratan pada LHS, jadi usulan saya untuk mengabaikan RHS akan menyelesaikan masalahnya juga.
Saya setuju bahwa memeriksa RHS &&
dan ||
adalah bug.
Saya juga cenderung melonggarkan pemeriksaan untuk LHS &&
, ||
dan operan !
. Ini hanya boleh diperiksa apakah ekspresi selalu benar atau selalu salah.
Itu hanya menyisakan kondisi if
, for
, while
, do ... while
dan ekspresi kondisional untuk pemeriksaan ketat untuk mengizinkan hanya boolean (atau apa pun yang dikonfigurasi ). Pikiran @adidahiya?
Saat ini mengaktifkan aturan ini dengan opsi konfigurasi yang tersedia akan memerlukan hari kerja dengan basis kode kami. :(
Saya mengaktifkannya dengan harapan akan mencegah konversi implisit number
, null
atau undefined
menjadi boolean
. Sebagai contoh:
if (!!array.length) { /* ... */ }
md5-d563d6246c0e981c16f8a2b3d7f53974
md5-430ec08bab82330fa4e519419e9ad014
However I find the following uses acceptable:
md5-70351fc6fdb328ee060919d6974e2cf4
```tsx
md5-036fd2ddd516eac8e1379cdcb9ac2b9a
Saya pikir ini setuju dengan apa yang disarankan @marcind .
Saya juga cenderung melonggarkan pemeriksaan LHS &&, || dan operan dari !.
@ajafff apakah ini akan melegalkan if (!!array.length)
atau if (!possiblyNull)
?
@ajafff @adidahiya ada pemikiran lebih lanjut di sini? Saya berada dalam situasi yang sama persis dengan @rhys-vdw.
Tanpa malu-malu mengiklankan proyek saya sendiri:
Sejak aktivitas terakhir saya dalam edisi ini, saya membuat linter saya sendiri, proyek Fimbullinter . Baca dokumen untuk memulai cepat: https://github.com/fimbullinter/wotan/blob/master/packages/wotan/README.md
Ini berisi aturan no-useless-predicate
, yang mungkin Anda cari. Ini adalah kombinasi dari strict-type-predicates
dan strict-boolean-expressions
TSLint, tetapi dengan beberapa perbedaan utama:
Berbeda dengan strict-type-predicates
TSLint juga berfungsi tanpa --strictNullChecks
dan menangani parameter tipe dan tipe objek kosong dengan benar. (mungkin tidak begitu menarik bagi orang-orang yang berlangganan masalah ini)
Perbedaan utama dengan strict-boolean-expressions
TSLint adalah bahwa ia tidak mengharuskan semuanya menjadi boolean (tidak mendeteksi paksaan implisit). Itu hanya membutuhkan setiap kondisi untuk menjadi mungkin benar dan salah.
Beberapa contoh:
if (0) {} // error, always falsy
if (1) {} // error, always truthy
declare let array: string[];
if (array.length) {} // no error
if (!array.length) {} // no error
if (!!array.length) {} // no error
if (array.length === undefined) {} // error, condition is always false
if (!!false) {} // 2 errors, because of the double negation of an always falsy value
declare let someString: string;
return someString || 'some default string'; // no error, because 'someString' might be falsy
declare const foo: 'bar' | 'baz';
return foo || 'bas'; // error, 'foo' is always truthy
declare let optionalFunction: (() => void) | undefined;
optionalFunction && optionalFunction(); // no error
Saya ingin mengikuti kasus penggunaan berikut dari kode saya yang sebenarnya:
export interface ILoggingRule {
readonly isFinal?: boolean;
readonly loggerNamePattern?: string;
readonly maxLogLevel?: LogLevel;
readonly minLogLevel?: LogLevel;
readonly target: Target;
}
// ...
/**
* Creates an instance of LoggingRule.
* <strong i="6">@param</strong> options Configuration options of the logging rule.
*/
public constructor(options: ILoggingRule) {
// tslint:disable:strict-boolean-expressions
this.isFinal = options.isFinal || false;
this.loggerNamePattern = options.loggerNamePattern || "*";
this.maxLogLevel = options.maxLogLevel || LogLevel.Fatal;
this.minLogLevel = options.minLogLevel || LogLevel.Trace;
this.target = options.target;
// tslint:enable:strict-boolean-expressions
}
Seperti yang Anda lihat, saya menggunakan ||
untuk menunjukkan nilai default jika LHS tidak terdefinisi. Apakah ada cara ringkas yang membuat tslint
mengerti bahwa ini mematuhi strict-boolean-expressions
? Kalau tidak, saya terpaksa menggunakan perintah nonaktifkan/aktifkan itu. (Anehnya ini hanya masalah dengan pemeriksaan tipe diaktifkan dan tidak di VSCode.)
Penggunaan ini standar dan sangat umum dan nyaman dalam JavaScript, dan seharusnya tidak memicu kegagalan aturan ini.
IMHO RHS &&
dan ||
tidak boleh diperiksa, untuk memungkinkan hubungan arus pendek. Ini harus menjadi perilaku default (atau setidaknya harus ada opsi seperti allow-any-rhs
). Saat ini, saya tidak dapat menggunakan strict-boolean-expressions
, karena ada banyak hubungan pendek di basis kode kami.
Memeriksa LHS harus tetap apa adanya IMHO, karena menggunakan string
atau number
sebagai LHS bisa berbahaya, lihat contoh ini:
function foo(x: string | number | null) {
return x || defaultValue;
}
Ini berbahaya karena banyak pengembang akan gagal untuk memahami bahwa tidak hanya null
tetapi juga 0
dan ""
akan menyebabkan defaultValue
dikembalikan.
Saya harus berurusan dengan bug utama dalam proyek saya, karena pengembang gagal mempertimbangkan bahwa ""
dan 0
juga salah. Mencegah kode semacam ini, adalah kasus penggunaan utama saya untuk strict-boolean-expressions
.
Diperbaiki di https://github.com/palantir/tslint/pull/4159 hanya perlu review dari kolaborator.
Ups, hanya ingin mengklarifikasi bahwa salah satu contoh saya buruk:
const x = possiblyUndefined || 5;
Itu seharusnya tidak berfungsi karena possiblyUndefined
mungkin 0
yang bisa menjadi kesalahan logika. Sepertinya PR @dobesv akan berfungsi di sini.
termasuk untuk array adalah fitur ES7.
Anda perlu mengubah konfigurasi ts Anda untuk menggunakan ES7 atau ESNEXT
Salam,
@rimiti Hai, saya tidak tahu apa yang Anda maksud, apakah Anda yakin Anda memposting komentar itu di utas yang benar?
@dobesv Oh, Anda benar, maaf;)
diperbaiki oleh #4159, akan tersedia di rilis berikutnya
Komentar yang paling membantu
Menurut pendapat saya,
strict-boolean-expressions
seharusnya hanya memeriksa operan kiri&&
dan||
. Operator tersebut (pada dasarnya) adalah gula untuk ternaries:a && b
sama dengana ? b : a
, dana || b
sama dengana ? a : b
. Ketika Anda memikirkannya dalam istilah itu, mengabaikan RHS sangat masuk akal, dan itu akan membawa perilaku untuk operator hubung singkat sejalan dengan perilaku untuk ternaries.Kemudian , jika semuanya ada di dalam if/for/while,
strict-boolean-conditions
bisa ikut bermain dan memeriksa ekspresi keseluruhan . Saya pikir ini akan mencakup semua kasus yang berguna, dan saya dapat mengaktifkan kembali aturan ini.Kode yang menandai ini sebagai masalah bagi saya adalah pola React umum yang terdokumentasi ini:
@ajafff Kodenya tidak lulus linter untuk saya, bahkan dengan semua opsi aturan diaktifkan, karena RHS konstan:
Maksud dari ekspresi itu adalah persyaratan pada LHS, jadi usulan saya untuk mengabaikan RHS akan menyelesaikan masalahnya juga.