TypeScript Version: 3.0.3
Istilah Pencarian: Ketik berdasarkan nilai dalam larik
Apakah ada fitur saat ini atau yang direncanakan untuk membuat tipe dari string dalam array?
Kode
const values = ['A', 'B']
type Foo = OneOf<values> // Is there a way of doing this?
const v1: Foo = 'A' // This should work
const v2: Foo = 'D' // This should give me an error since 'D' doesn't exist in values
Mirip dengan cara kerja keyof
:
const values = {
A: 'A',
B: 'B'
}
type Foo = keyof typeof values
const v1: Foo = 'A'
const v2: Foo = 'D' // Type '"D"' is not assignable to type '"A" | "B"'
Masalah Terkait:https://github.com/Microsoft/TypeScript/issues/20965
Tautan ke taman bermain http://www.typescriptlang.org/play/#src = biarkan% 20vals1% 20% 3D% 20% 5B'A '% 2C% 20'B'% 5D% 0D% 0 Jenis% 20Foo1% 20% 3D% 20OneOf% 3Cvals1% 3E% 20% 2F% 2F% 20Is% 20there% 20a% 20way% 20of% 20doing% 20this% 3F% 0D% 0A% 0D% 0Alet% 20v1% 3A% 20Foo1% 20% 3D% 20 ' A '% 20% 2F% 2F% 20Ini% 20harus% 20work% 0D% 0Alet% 20v2% 3A% 20Foo1% 20% 3D% 20'D'% 20% 2F% 2F% 20Ini% 20harus% 20memberikan% 20me% 20an% 20 kesalahan% 20 sejak% 20'D '% 20tidak% 20 ada% 20in% 20 nilai% 0D% 0A% 0D% 0Alet% 20vals2% 20% 3D% 20% 7B% 0D% 0A% 20% 20A% 3A% 20'A '% 2C% 0D% 0A% 20% 20B% 3A% 20'B'% 0D% 0A% 7D% 0D% 0 Jenis% 20Foo2% 20% 3D% 20keyof% 20type% 20vals2% 0D% 0Alet% 20v3% 3A% 20Foo2 % 20% 3D% 20'A '% 0D% 0Alet% 20v4% 3A% 20Foo2% 20% 3D% 20'D'% 20% 2F% 2F% 20Type% 20 '% 22D% 22'% 20is% 20not% 20 assignable % 20 hingga% 20 jenis% 20 '% 22A% 22% 20% 7C% 20% 22B% 22'
keyof
hanya berfungsi karena menggunakan informasi yang diketahui secara statis pada waktu kompilasi. Jenis di TS sepenuhnya dapat dihapus dan tidak ada dalam kode yang ditranspilasi, jadi tidak mungkin untuk membuat jenis berdasarkan konten runtime dari sebuah larik.
Ini mungkin:
function stringLiterals<T extends string>(...args: T[]): T[] { return args; }
type ElementType<T extends ReadonlyArray<unknown>> = T extends ReadonlyArray<infer ElementType> ? ElementType : never;
const values = stringLiterals('A', 'B');
type Foo = ElementType<typeof values>;
const v1: Foo = 'A' // This should work
const v2: Foo = 'D' // This should give me an error since 'D' doesn't exist in values
Jelas tidak jelas bagaimana melakukan ini. # 27179 terkait.
Itu masih menggunakan informasi yang dikenal secara statis oleh kompilator; pada saat itu saya tidak mengerti apa keuntungan dari sekedar mengatakan ”A” | “B”
.
@fatcerberus Berguna untuk menghindari pengulangan informasi - jika Anda hanya menulis const values = ["A", "B"]; type Foo = "A" | "B";
, mudah bagi seseorang untuk mengubah salah satunya sementara lupa untuk mengubah yang lain. Anda dapat menulis const values: Foo[] =["A", "B"];
, tetapi itu masih rentan dengan menambahkan entri tambahan ke Foo
dan lupa memasukkannya ke dalam values
.
Di mana kita sekarang?
Seperti yang dikatakan @ andy-ms, akan sangat berguna untuk menghindari pengulangan informasi secara manual.
Dan seperti yang dikatakan @fatcerberus , tipe sepenuhnya dapat dihapus. Terkadang kita perlu memeriksa data runtime yang kita dapatkan misalnya dari bagian aplikasi yang tidak murni (seperti layanan web, atau dari pengguna).
Berdasarkan jawaban @ andy-ms, dan menggunakan pernyataan konstanta yang diperkenalkan dalam skrip ketikan 3.4, sekarang mungkin untuk melakukan sesuatu seperti ini
const values = ['A', 'B'] as const
type ElementType < T extends ReadonlyArray < unknown > > = T extends ReadonlyArray<
infer ElementType
>
? ElementType
: never
type Foo = ElementType<typeof values> // this is correctly inferred as literal "A" | "B"
Masalah ini telah ditandai sebagai 'Pertanyaan' dan tidak melihat aktivitas terbaru. Itu telah ditutup secara otomatis untuk keperluan rumah tangga. Jika Anda masih menunggu jawaban, pertanyaan biasanya lebih cocok untuk stackoverflow .
di [email protected] dan di atasnya. selesaikan seperti ini
export const type = <const>[
'room',
'room_with_gifter',
'user_send'
];
export interface Activity {
id?: string;
type: typeof type[number];
}
Daripada ini:
export const items = <const>[
'room',
'room_with_gifter',
'user_send'
];
export interface Activity {
id?: string;
type: typeof items[number];
}
Kamu bisa melakukan ini:
export const items = [
'room',
'room_with_gifter',
'user_send'
] as const;
export type Item = typeof items;
export interface Activity {
id?: string;
type: Item;
}
_Sangat tidak suka menggunakan type
sebagai nama variabel._
@ 7
di [email protected] dan di atasnya. selesaikan seperti ini
export const type = <const>[ 'room', 'room_with_gifter', 'user_send' ]; export interface Activity { id?: string; type: typeof type[number]; }
Sekarang bagaimana jika saya memiliki ini di kelas?
class Class {
const list = <const>[
'room',
'room_with_gifter',
'user_send'
];
const withType: typeof list[number];
}
Tidak bekerja. Saya juga tidak bisa melakukan this.list[number]
. Juga, khusus saya
usecase, saya tidak dapat menyetel list
menjadi static
@ 7
di [email protected] dan di atasnya. selesaikan seperti ini
export const type = <const>[ 'room', 'room_with_gifter', 'user_send' ]; export interface Activity { id?: string; type: typeof type[number]; }
Sekarang bagaimana jika saya memiliki ini di kelas?
class Class { const list = <const>[ 'room', 'room_with_gifter', 'user_send' ]; const withType: typeof list[number]; }
Tidak bekerja. Saya juga tidak bisa melakukan
this.list[number]
. Juga, khusus saya
usecase, saya tidak dapat menyetellist
menjadistatic
@vegerot Anda tidak dapat menggunakan const
secara langsung dalam lingkup class
, jadi sintaksnya salah.
@ 7
di [email protected] dan di atasnya. selesaikan seperti ini
export const type = <const>[ 'room', 'room_with_gifter', 'user_send' ]; export interface Activity { id?: string; type: typeof type[number]; }
Sekarang bagaimana jika saya memiliki ini di kelas?
class Class { const list = <const>[ 'room', 'room_with_gifter', 'user_send' ]; const withType: typeof list[number]; }
Tidak bekerja. Saya juga tidak bisa melakukan
this.list[number]
. Juga, khusus saya
usecase, saya tidak dapat menyetellist
menjadistatic
@vegerot Anda tidak dapat menggunakan
const
secara langsung dalam lingkupclass
, jadi sintaksnya salah.
@ 7Saya buruk. Saya menyalin dan menempel terlalu banyak. Yang ingin saya katakan adalah
class Class {
private list = <const>[
'room',
'room_with_gifter',
'user_send'
];
private withType: typeof list[number];
// OR
private withType2: typeof this.list[number];
}
dll semua tidak bekerja.
Juga, untuk kasus penggunaan khusus saya, saya tidak dapat menyetel daftar menjadi statis
@ 7
di [email protected] dan di atasnya. selesaikan seperti ini
export const type = <const>[ 'room', 'room_with_gifter', 'user_send' ]; export interface Activity { id?: string; type: typeof type[number]; }
Sekarang bagaimana jika saya memiliki ini di kelas?
class Class { const list = <const>[ 'room', 'room_with_gifter', 'user_send' ]; const withType: typeof list[number]; }
Tidak bekerja. Saya juga tidak bisa melakukan
this.list[number]
. Juga, khusus saya
usecase, saya tidak dapat menyetellist
menjadistatic
@vegerot Anda tidak dapat menggunakan
const
secara langsung dalam lingkupclass
, jadi sintaksnya salah.@ 7Saya buruk. Saya menyalin dan menempel terlalu banyak. Yang ingin saya katakan adalah
class Class { private list = <const>[ 'room', 'room_with_gifter', 'user_send' ]; private withType: typeof list[number]; // OR private withType2: typeof this.list[number]; }
dll semua tidak bekerja.
Juga, untuk kasus penggunaan khusus saya, saya tidak dapat menyetel daftar menjadi statis
class Class {
private list = [
"room",
"room_with_gifter",
"user_send"
] as const
private withType: Class["list"][number]
}
@vegerot Bagaimana dengan ini?
@eyal itu luar biasa! Terima kasih. Saya pikir solusinya akan melibatkan typeof
atau sesuatu. Apakah Anda akan memberikan penjelasan singkat tentang cara kerjanya, atau tautkan saya ke buku pegangan di mana hal ini dibahas?
@eyal itu luar biasa! Terima kasih. Saya pikir solusinya akan melibatkan
typeof
atau sesuatu. Apakah Anda akan memberikan penjelasan singkat tentang cara kerjanya, atau tautkan saya ke buku pegangan di mana hal ini dibahas?
@vegerot Tentu, saya yakin ini adalah "Jenis indeks". Ini dia di Buku Pegangan: https://www.typescriptlang.org/docs/handbook/advanced-types.html#index -types
Senang aku dapat membantu!
Hai% username%, jika ElementType
solusi juga tidak berfungsi untuk Anda,
perhatikan as const
after array . Ini penting
Komentar yang paling membantu
di [email protected] dan di atasnya. selesaikan seperti ini