Inilah yang saya miliki di fruit.ts
export type Fruit = "Orange" | "Apple" | "Banana"
Sekarang saya mengimpor fruit.ts dalam file naskah lain. Inilah yang saya miliki
myString:string = "Banana";
myFruit:Fruit = myString;
Kapan saya melakukannya
myFruit = myString;
Saya mendapatkan kesalahan:
Ketik 'string' tidak dapat ditentukan untuk mengetik '"Oranye" | "Apple" | "Pisang"'
Bagaimana saya bisa menetapkan string ke variabel jenis kustom Buah?
javascript
typescript
angular
pengguna6123723
sumber
sumber
export type Fruit
?Jawaban:
Anda harus membuatnya :
Juga perhatikan bahwa ketika menggunakan string literal Anda hanya perlu menggunakan satu
|
Edit
Seperti disebutkan dalam jawaban lain oleh @Simon_Weaver, sekarang mungkin untuk menegaskannya ke
const
:sumber
const myFruit: Fruit = "Banana"
akan dilakukan.let myFruit:Fruit = "Apple" let something:string = myFruit as string
Ini memberi saya kesalahan: Konversi tipe 'Buah' ke tipe 'string' mungkin merupakan kesalahan.as string
bagian itu. Saya sudah mencoba kode Anda di taman bermain dan tidak ada kesalahan.const myString: string = 'Bananaaa';
saya tidak mendapatkan kesalahan kompilasi karena casting ... apakah tidak ada cara untuk melakukan ini saat mengetik memeriksa string?Scriptants
3.4
memperkenalkan pernyataan 'const' yang baruAnda sekarang dapat mencegah tipe literal (mis.
'orange'
Atau'red'
) 'diperlebar' untuk mengetikstring
dengan apa yang disebutconst
pernyataan tegas.Anda akan dapat melakukan:
Dan kemudian itu tidak akan berubah menjadi
string
lagi - yang merupakan akar masalah dalam pertanyaan.sumber
let fruit = 'orange' as const;
ketika mengikuti aturan no-sudut-braket-jenis-penegasanKetika Anda melakukan ini:
... Anda membuat tipe yang disebut
Fruit
yang hanya bisa berisi literal"Orange"
,"Apple"
dan"Banana"
. Tipe ini meluasString
, karenanya dapat ditugaskan untukString
. Namun,String
TIDAK meluas"Orange" | "Apple" | "Banana"
, sehingga tidak dapat ditugaskan untuk itu.String
adalah kurang spesifik . Itu bisa berupa string apa saja .Ketika Anda melakukan ini:
...berhasil. Mengapa? Karena sebenarnya jenis dari
myString
dalam contoh ini adalah"Banana"
. Ya,"Banana"
adalah tipenya . Itu meluasString
jadi itu ditugaskan untukString
. Selain itu, suatu jenis memperluas Jenis Serikat saat meluas apa pun satu komponennya. Dalam hal ini,"Banana"
tipe tersebut memanjang"Orange" | "Apple" | "Banana"
karena memanjang salah satu komponennya. Oleh karena itu,"Banana"
ditugaskan untuk"Orange" | "Apple" | "Banana"
atauFruit
.sumber
<'Banana'> 'Banana'
dan yang akan 'melemparkan'"Banana"
string ke"Banana"
tipe !!!<const> 'Banana'
yang lebih baik :-)Saya melihat ini agak lama, tetapi mungkin ada solusi yang lebih baik di sini.
Saat Anda menginginkan string, tetapi Anda ingin string hanya cocok dengan nilai-nilai tertentu, Anda bisa menggunakan enum .
Sebagai contoh:
Sekarang Anda akan tahu bahwa apa pun yang terjadi, myFruit akan selalu menjadi string "Banana" (Atau nilai enumerable apa pun yang Anda pilih). Ini berguna untuk banyak hal, apakah itu mengelompokkan nilai yang sama seperti ini, atau memetakan nilai yang ramah pengguna ke nilai yang ramah mesin, semuanya sambil menegakkan dan membatasi nilai yang diizinkan oleh kompiler.
sumber
let myFruit: Fruit = "Banana"
.Ada beberapa situasi yang akan memberi Anda kesalahan khusus ini. Dalam kasus OP ada nilai yang didefinisikan secara eksplisit sebagai string . Jadi saya harus berasumsi bahwa mungkin ini berasal dari dropdown, atau layanan web atau string JSON mentah.
Dalam hal ini pemeran sederhana
<Fruit> fruitString
ataufruitString as Fruit
satu-satunya solusi (lihat jawaban lain). Anda tidak akan pernah bisa memperbaiki ini pada waktu kompilasi. [ Sunting: Lihat jawaban saya yang lain tentang<const>
]!Namun sangat mudah untuk mengalami kesalahan yang sama ketika menggunakan konstanta dalam kode Anda yang tidak pernah dimaksudkan untuk menjadi tipe string . Jawaban saya berfokus pada skenario kedua:
Pertama-tama: Mengapa konstanta string 'ajaib' seringkali lebih baik daripada enum?
Untungnya saat Anda mendefinisikan:
export type FieldErrorType = 'none' | 'missing' | 'invalid'
... Anda benar-benar mendefinisikan penyatuan jenis mana
'missing'
sebenarnya merupakan tipe!Saya sering mengalami kesalahan 'tidak dapat ditugaskan' jika saya memiliki string seperti
'banana'
dalam naskah saya dan berpikir kompiler saya maksudkan sebagai string, sedangkan saya benar-benar ingin itu menjadi tipebanana
. Seberapa pintar kompiler dapat bergantung pada struktur kode Anda.Berikut adalah contoh ketika saya mendapat kesalahan ini hari ini:
Segera setelah saya menemukan itu
'invalid'
atau'banana'
bisa berupa tipe atau string, saya menyadari bahwa saya hanya bisa menegaskan string ke tipe itu . Pada dasarnya melemparkannya ke dirinya sendiri , dan katakan kompiler tidak, saya tidak ingin ini menjadi string !Jadi apa yang salah dengan 'casting' untuk
FieldErrorType
(atauFruit
)Ini bukan waktu kompilasi yang aman:
Mengapa? Ini adalah naskah jadi
<FieldErrorType>
adalah pernyataan dan Anda memberi tahu kompiler bahwa anjing adalah FieldErrorType ! Dan kompiler akan mengizinkannya!TETAPI jika Anda melakukan hal berikut, maka kompiler akan mengubah string menjadi tipe
Berhati-hatilah terhadap kesalahan ketik bodoh seperti ini:
Cara lain untuk memecahkan masalah adalah dengan melemparkan objek induk:
Definisi saya adalah sebagai berikut:
jenis ekspor FieldName = 'angka' | | 'Tanggal kadaluwarsa' | 'cvv'; jenis ekspor FieldError = 'tidak ada' | 'hilang' | 'tidak valid'; jenis ekspor FieldErrorType = {bidang: FieldName, kesalahan: FieldError};
Katakanlah kita mendapatkan kesalahan dengan ini (string tidak dapat ditugaskan kesalahan):
Kita dapat 'menegaskan' seluruh objek sebagai
FieldErrorType
berikut:Maka kita menghindari keharusan melakukannya
<'invalid'> 'invalid'
.Tapi bagaimana dengan kesalahan ketik? Tidak
<FieldErrorType>
hanya menegaskan apa pun yang berhak menjadi tipe itu. Tidak dalam kasus ini - untungnya kompiler AKAN mengeluh jika Anda melakukan ini, karena cukup pintar untuk mengetahui bahwa itu tidak mungkin:sumber
Semua jawaban di atas valid, namun, ada beberapa kasus bahwa Tipe Literal String adalah bagian dari tipe kompleks lainnya. Perhatikan contoh berikut:
Anda memiliki beberapa solusi untuk memperbaikinya. Setiap solusi valid dan memiliki kasus penggunaannya sendiri.
1) Solusi pertama adalah menentukan tipe untuk ukuran dan mengekspornya dari foo.ts. Ini bagus jika ketika Anda perlu bekerja dengan parameter ukuran sendiri. Misalnya, Anda memiliki fungsi yang menerima atau mengembalikan parameter ukuran tipe dan Anda ingin mengetiknya.
2) Pilihan kedua adalah dengan hanya membuangnya ke tipe ToolbarTheme. Dalam hal ini, Anda tidak perlu mengekspos internal ToolbarTheme jika Anda tidak perlu.
sumber
Jika Anda casting ke a
dropdownvalue[]
Misalnya, data yang mengejek, buatlah itu sebagai array objek dengan nilai dan properti tampilan.contoh :
sumber
Saya menghadapi masalah yang sama, saya membuat perubahan di bawah ini dan masalah ini terselesaikan.
Buka file watchQueryOptions.d.ts
Ubah tipe kueri apa pun alih-alih DocumentNode , Sama untuk mutasi
Sebelum:
Setelah:
sumber