Beberapa hari yang lalu kami mengumumkan ketersediaan kandidat rilis kami (RC) dari TypeScript 3.4. Harapan kami adalah untuk mengumpulkan umpan balik dan masalah awal untuk memastikan rilis akhir kami mudah untuk diambil dan digunakan segera.
Untuk mulai menggunakan RC, Anda bisa mendapatkannya melalui NuGet , atau menggunakan npm dengan perintah berikut:
npm install -g typescript@rc
Anda juga dapat memperoleh dukungan editor dengan
Mari menjelajahi apa yang baru dalam 3.4!
Artikel ini di blog kami.--incremental
selanjutnya yang lebih cepat dengan bendera --incremental
Karena file TypeScript dikompilasi, itu memperkenalkan langkah menengah antara menulis dan menjalankan kode Anda. Salah satu tujuan kami adalah untuk meminimalkan waktu yang dibuat mengingat perubahan apa pun pada program Anda. Salah satu cara untuk melakukannya adalah dengan menjalankan TypeScript dalam mode --watch
. Ketika file berubah dalam mode --watch
, TypeScript dapat menggunakan grafik dependensi proyek Anda yang telah dibangun sebelumnya untuk menentukan file mana yang berpotensi terpengaruh dan perlu diperiksa ulang dan berpotensi dipancarkan kembali. Ini dapat menghindari pengecekan tipe-penuh dan memancarkan kembali yang bisa mahal.
Tapi itu tidak realistis untuk mengharapkan semua pengguna untuk menjaga tsc --watch
proses tsc --watch
berjalan semalam hanya untuk membangun lebih cepat besok pagi. Bagaimana dengan cold build? Selama beberapa bulan terakhir, kami telah berupaya untuk melihat apakah ada cara untuk menyimpan informasi yang sesuai dari mode --watch
ke file dan menggunakannya dari build hingga build.
TypeScript 3.4 memperkenalkan flag baru bernama --incremental
yang memberitahu TypeScript untuk menyimpan informasi tentang grafik proyek dari kompilasi terakhir. Saat berikutnya TypeScript dipanggil dengan --incremental
, itu akan menggunakan informasi itu untuk mendeteksi cara paling murah untuk mengetik-periksa dan memancarkan perubahan pada proyek Anda.
Secara default dengan pengaturan ini, ketika kita menjalankan tsc
, TypeScript akan mencari file bernama .tsbuildinfo
di direktori output kami ( ./lib
). Jika ./lib/.tsbuildinfo
tidak ada, itu akan dihasilkan. Tetapi jika ya, tsc
akan mencoba menggunakan file itu untuk secara bertahap mengetikkan dan memperbarui file output kami.
File .tsbuildinfo
ini dapat dihapus dengan aman dan tidak berdampak pada kode kami saat runtime - mereka murni digunakan untuk membuat kompilasi lebih cepat. Kita juga dapat memberi nama mereka apa pun yang kita inginkan, dan menempatkannya di mana saja yang kita inginkan menggunakan flag --tsBuildInfoFile
.
Selama tidak ada orang lain yang mencoba menulis ke file cache yang sama, kita harus dapat menikmati build dingin inkremental yang lebih cepat.
Proyek komposit
Bagian dari maksud dengan proyek komposit ( tsconfig.json
's dengan set composite
ke true
) adalah bahwa referensi antara proyek yang berbeda dapat dibangun secara bertahap. Dengan demikian, proyek komposit akan selalu menghasilkan file .tsbuildinfo
.
outFile
Ketika outFile
digunakan, nama file informasi build akan didasarkan pada nama file output. Sebagai contoh, jika file JavaScript output kami adalah ./output/foo.js
, maka di bawah flag --incremental, TypeScript akan menghasilkan file ./output/foo.tsbuildinfo
. Seperti di atas, ini dapat dikontrol dengan flag --tsBuildInfoFile
.
Format file dan versi - --incremental
Meskipun file yang dihasilkan oleh --incremental
adalah JSON, file tersebut tidak berarti dikonsumsi oleh alat lain. Kami tidak dapat memberikan jaminan stabilitas untuk isinya, dan pada kenyataannya, kebijakan kami saat ini adalah bahwa salah satu versi dari TypeScript tidak akan mengerti file .tsbuildinfo
dihasilkan dari versi lain.
Perbaikan untuk ReadonlyArray
dan readonly
tuple
TypeScript 3.4 membuatnya sedikit lebih mudah untuk menggunakan tipe read-only array-like.
Sintaks baru untuk ReadonlyArray
Tipe ReadonlyArray
menggambarkan Array
s yang hanya dapat dibaca. Variabel apa pun dengan pegangan ke ReadonlyArray
tidak dapat menambah, menghapus, atau mengganti elemen array apa pun.
function foo(arr: ReadonlyArray<string>) { arr.slice();
Meskipun sering kali merupakan praktik yang baik untuk menggunakan ReadonlyArray
atas Array
untuk tujuan maksud, sering kali terasa menyakitkan karena array memiliki sintaks yang lebih bagus. Secara khusus, number[]
adalah versi singkatan dari Array<number>
, sama seperti Date[]
adalah singkatan untuk Array<Date>
.
TypeScript 3.4 memperkenalkan sintaks baru untuk ReadonlyArray
menggunakan pengubah readonly
baru untuk tipe array.
function foo(arr: readonly string[]) { arr.slice();
tuple readonly
TypeScript 3.4 juga memperkenalkan dukungan baru untuk tuple readonly
. Kita dapat mengawali setiap jenis tuple dengan kata kunci readonly
untuk menjadikannya tuple readonly
, seperti halnya kita sekarang dapat dengan sintaksis array shorthand. Seperti yang Anda duga, tidak seperti tuple biasa yang slotnya dapat ditulis, tuple readonly
hanya mengizinkan pembacaan dari posisi itu.
function foo(pair: readonly [string, string]) { console.log(pair[0]);
Cara yang sama dengan tupel biasa adalah tipe yang memanjang dari Array
- tuple dengan elemen tipe T
1
, T
2
, ... T
n
memanjang dari Array<
T
1
| T
2
| ... T
n
>
- readonly
tuple adalah tipe yang diperluas dari ReadonlyArray
. Jadi tuple readonly
dengan elemen T
1
, T
2
, ... T
n
memanjang dari ReadonlyArray<
T
1
| T
2
| ... T
n
>
.
pengubah tipe readonly
dipetakan dan array readonly
Dalam versi sebelumnya dari TypeScript, kami menggeneralisasi tipe yang dipetakan untuk beroperasi secara berbeda pada tipe array-like. Ini berarti bahwa tipe yang dipetakan seperti Boxify
dapat bekerja pada array dan tuple.
interface Box<T> { value: T } type Boxify<T> = { [K in keyof T]: Box<T[K]> }
Sayangnya, tipe yang dipetakan seperti tipe utilitas Readonly
secara efektif no-ops pada tipe array dan tuple.
Dalam TypeScript 3.4, pengubah readonly
dalam tipe yang dipetakan akan secara otomatis mengkonversi tipe seperti array ke rekan readonly
sesuai.
Demikian pula, Anda dapat menulis jenis utilitas seperti jenis dipetakan Writable
yang menghapus readness -ness, dan yang akan mengkonversi wadah array readonly
kembali ke setara mereka yang bisa berubah.
type Writable<T> = { -readonly [K in keyof T]: T[K] }
Peringatan
Terlepas dari kemunculannya, pengubah tipe hanya- readonly
hanya dapat digunakan untuk sintaks pada tipe array dan tipe tuple. Ini bukan tipe operator tujuan umum.
let err1: readonly Set<number>;
pernyataan const
Ketika mendeklarasikan variabel atau properti yang bisa berubah, TypeScript sering memperluas nilai untuk memastikan bahwa kita dapat menetapkan hal-hal nanti tanpa menulis tipe eksplisit.
let x = "hello";
Secara teknis, setiap nilai literal memiliki tipe literal. Di atas, tipe "hello"
diperlebar ke string
tipe sebelum menyimpulkan tipe untuk x
.
Salah satu pandangan alternatif mungkin mengatakan bahwa x
memiliki tipe literal asli "hello"
dan bahwa kita tidak dapat menetapkan "world"
nanti seperti:
let x: "hello" = "hello";
Dalam hal ini, itu tampak ekstrem, tetapi dapat berguna dalam situasi lain. Sebagai contoh, TypeScripters sering membuat objek yang dimaksudkan untuk digunakan dalam serikat yang didiskriminasi.
type Shape = | { kind: "circle", radius: number } | { kind: "square", sideLength: number } function getShapes(): readonly Shape[] { let result = [ { kind: "circle", radius: 100, }, { kind: "square", sideLength: 50, }, ];
Mutability adalah salah satu heuristik niat terbaik yang TypeScript dapat gunakan untuk menentukan kapan harus melebar (daripada menganalisis seluruh program kami).
Sayangnya, seperti yang kita lihat pada contoh terakhir, dalam properti JavaScript bisa berubah secara default. Ini berarti bahwa bahasa tersebut akan sering memperluas jenis yang tidak diinginkan, membutuhkan jenis eksplisit di tempat-tempat tertentu.
function getShapes(): readonly Shape[] {
Sampai pada titik tertentu ini tidak apa-apa, tetapi karena struktur data kami menjadi semakin kompleks, ini menjadi rumit.
Untuk mengatasi ini, TypeScript 3.4 memperkenalkan konstruksi baru untuk nilai-nilai literal yang disebut pernyataan const
. Sintaksnya adalah pernyataan tipe dengan const
menggantikan nama tipe (mis. 123 as const
). Ketika kita membangun ekspresi literal baru dengan pernyataan const
, kita dapat memberi sinyal ke bahasa itu
- tidak ada tipe literal dalam ekspresi yang harus diperlebar (mis. tidak beralih dari
"hello"
ke string
) - objek literal mendapatkan properti hanya
readonly
- array literal menjadi tupel hanya
readonly
Di luar file .tsx
, sintaks pernyataan braket sudut juga dapat digunakan.
Fitur ini sering berarti bahwa tipe-tipe yang seharusnya digunakan hanya untuk mengisyaratkan ketidakberubahan pada kompiler seringkali dapat dihilangkan.
Perhatikan penjelasan di atas tidak diperlukan jenis. Pernyataan const
memungkinkan TypeScript untuk mengambil tipe ekspresi yang paling spesifik.
Peringatan
Satu hal yang perlu diperhatikan adalah bahwa pernyataan const
hanya dapat diterapkan segera pada ekspresi literal sederhana.
Hal lain yang perlu diingat adalah bahwa konteks const
tidak segera mengubah ekspresi menjadi tidak berubah sepenuhnya.
let arr = [1, 2, 3, 4]; let foo = { name: "foo", contents: arr, }; foo.name = "bar";
Ketik-periksa untuk globalThis
Bisa jadi sangat sulit untuk mengakses atau mendeklarasikan nilai dalam lingkup global, mungkin karena kita sedang menulis kode kita dalam modul (yang deklarasi lokalnya tidak bocor secara default), atau karena kita mungkin memiliki variabel lokal yang membayangi nama nilai global. Di lingkungan yang berbeda, ada berbagai cara untuk mengakses apa yang secara efektif ruang lingkup global - global
di Node, window
, self
, atau frames
di browser, atau this
di lokasi tertentu di luar mode ketat. Tidak ada yang jelas, dan sering membuat pengguna merasa tidak yakin apakah mereka menulis kode yang benar.
TypeScript 3.4 memperkenalkan dukungan untuk pengecekan tipe-global ECMAScript baru ini - variabel global yang mengacu pada cakupan global. Berbeda dengan solusi di atas, globalThis
memberikan cara standar untuk mengakses ruang lingkup global yang dapat digunakan di berbagai lingkungan.
globalThis
juga dapat mencerminkan apakah variabel global dideklarasikan sebagai const
dengan memperlakukannya sebagai properti hanya readonly
saat diakses.
const answer = 42; globalThis.answer = 333333;
Penting untuk dicatat bahwa TypeScript tidak mengubah referensi ke globalThis
ketika mengkompilasi ke versi ECMAScript yang lebih lama. Dengan demikian, kecuali Anda menargetkan browser yang selalu hijau (yang sudah mendukung globalThis
), Anda mungkin ingin menggunakan polyfill yang sesuai sebagai gantinya.
Konversikan ke parameter bernama
Terkadang, daftar parameter mulai menjadi berat.
function updateOptions( hue?: number, saturation?: number, brightness?: number, positionX?: number, positionY?: number positionZ?: number) {
Dalam contoh di atas, terlalu mudah bagi penelepon untuk mencampur urutan argumen yang diberikan. Pola JavaScript yang umum adalah sebagai gantinya menggunakan "objek opsi", sehingga setiap opsi secara eksplisit diberi nama dan urutan tidak pernah masalah. Ini mengemulasi fitur yang oleh bahasa lain disebut "parameter bernama".
interface Options { hue?: number, saturation?: number, brightness?: number, positionX?: number, positionY?: number positionZ?: number } function updateOptions(options: Options = {}) {
Tim TypeScript tidak hanya bekerja pada kompiler - kami juga menyediakan fungsionalitas yang editor gunakan untuk fitur yang kaya seperti penyelesaian, pergi ke definisi, dan refactor. Dalam TypeScript 3.4, staf magang kami Gabriela Britto telah menerapkan refactoring baru untuk mengonversi fungsi yang ada untuk menggunakan pola "bernama parameter" ini.

Meskipun kami dapat mengubah nama fitur dengan rilis final 3.4 kami dan kami percaya mungkin ada ruang untuk beberapa ergonomi, kami akan senang bagi Anda untuk mencoba fitur tersebut dan memberi kami umpan balik Anda.
Memecah perubahan
Level this
ini sekarang diketik
Jenis tingkat this
ini sekarang diketik sebagai jenis typeof globalThis
bukan any
. Sebagai konsekuensinya, Anda mungkin menerima kesalahan untuk mengakses nilai yang tidak diketahui pada this
bawah noImplicitAny
.
Perhatikan bahwa kode yang dikompilasi di bawah noImplicitThis
tidak akan mengalami perubahan apa pun di sini.
Argumen tipe umum yang disarankan
Dalam kasus-kasus tertentu, inferensi TypeScript 3.4 yang ditingkatkan mungkin menghasilkan fungsi yang generik, bukan yang mengambil dan mengembalikan kendala mereka (biasanya {}
).
declare function compose<T, U, V>(f: (arg: T) => U, g: (arg: U) => V): (arg: T) => V; function list<T>(x: T) { return [x]; } function box<T>(value: T) { return { value }; } let f = compose(list, box); let x = f(100)
Anotasi jenis eksplisit pada x
dapat menghilangkan kesalahan.
Apa selanjutnya
TypeScript 3.4 adalah rilis pertama kami yang memiliki rencana iterasi yang menguraikan rencana kami untuk rilis ini, yang dimaksudkan untuk menyelaraskan dengan peta jalan 6 bulan kami . Anda dapat mengawasi keduanya, dan pada halaman roadmap fitur bergulir kami untuk pekerjaan yang akan datang.
Saat ini kami sedang menantikan untuk mendengar tentang pengalaman Anda dengan RC, jadi cobalah sekarang dan beri tahu kami pendapat Anda!