Versi TypeScript: 2.1.1
Kode
type A = { a: string; }
type B = { b: string; }
type AorB = A | B;
declare const AorB: AorB;
if (AorB.a) {
// use AorB.a
}
Perilaku yang diharapkan:
Kode dikompilasi tanpa kesalahan. Meskipun a
tidak (harus) ada di semua konstituen serikat, fakta bahwa itu ada di beberapa harus memungkinkan saya untuk memeriksa .a
dan menggunakannya jika ada.
Perilaku sebenarnya:
Ketikan keluhan: "Properti a tidak ada di tipe AorB ... Properti a tidak ada di tipe B."
Dokter mengatakan:
Agar kode yang sama berfungsi, kita perlu menggunakan pernyataan tipe:
let pet = getSmallPet();
if ((<Fish>pet).swim) {
(<Fish>pet).swim();
}
else {
(<Bird>pet).fly();
}
http://www.typescriptlang.org/docs/handbook/advanced-types.html
Kemudian dalam sampel Anda:
if ((<A>AorB).a) {
// use AorB.a
}
Masalahnya di sini adalah karena B
tidak mendeklarasikan properti a
, mungkin pada saat run-time memiliki properti a
dari jenis yang mungkin (karena Anda dapat menetapkan objek dengan set properti apa pun menjadi B
selama ia memiliki properti tipe string b
). Anda dapat membuatnya bekerja secara eksplisit dengan mendeklarasikan properti a: undefined
di B
(dengan demikian memastikan bahwa B
tidak akan memiliki properti a
acak):
type A = { a: string; }
type B = { b: string; a: undefined }
type AorB = A | B;
declare const AorB: AorB;
if (AorB.a) {
// Ok
}
Masuk akal. Otak kentut.
Jika Anda menentukan a: undefined
pada tipe B, Anda harus menyetelnya ke undefined
saat Anda membuat / meneruskan variabel.
Untuk menyiasatinya, Anda dapat mendeklarasikan a
sebagai a?: undefined
, dan skrip akan senang jika Anda menghilangkannya.
Jika saya memahami komentar dengan benar, ini seharusnya berfungsi (tetapi melempar; diuji di taman bermain): Apakah ini bug atau tidak? 🤔
type LinkProps = {
to: string;
onClick?: undefined;
// Link specific props:
target: string;
}
type ButtonProps = {
to?: undefined;
onClick: Function;
// Button specific props:
disabled: boolean;
}
type ActionProps = LinkProps | ButtonProps;
const Action = (props: ActionProps) =>
props.to ?
'Link with target: ' + props.target // Error not on ButtonProps
:
'Button with disabled: ' + props.disabled; // Error: not on LinkProps
Action({
to: 'dssd',
target: '_blank'
});
Saya tidak mengerti sama sekali. Bukankah if ((<A>AorB).a)
sama dengan menggunakan if (A.a)
karena Anda memaksanya kembali mengetik A
?
Jika Anda menentukan
a: undefined
pada tipe B, Anda harus menyetelnya keundefined
saat Anda membuat / meneruskan variabel.
Untuk menyiasatinya, Anda dapat mendeklarasikana
sebagaia?: undefined
, dan skrip akan senang jika Anda menghilangkannya.
mungkin lebih baik a?: never
, sekarang Anda tidak dapat menetapkan undefined
karena kesalahan
Bagaimana jika Anda tidak memberikan nama kepada setiap anggota serikat? (tidak dapat membuat pernyataan tipe seperti di atas tanpa nama untuk tipe yang ditegaskan, bukan?)
type u = "str" | {prop:"val"};
function f(arg:u){return arg.prop} // TypeScript: Property 'prop' does not exist on type 'u'
Ada solusi?
saya menemukan solusi di buku:
interface A { x: number;}
interface B { y: string;}
function doStuff ( q: A | B ) {
if ( 'x' in q) {
// if type A...
}
else {
// if type B...
}
}
Kutipan Dari: Basarat Ali Syed. “TypeScript Deep Dive.” Apple Books.
properti pada objek dan dapat digunakan sebagai pelindung tipe, dan TypeScript dapat mengetahui tipe yang Anda gunakan.
type ColorItemType = {
colorId: number,
colorName: string,
}
type NumItemType = {
numId: number,
numName: string
}
type ResType = {
itemId: number,
// 0 color 1 num
type: number,
itemInfo: {
colorList: Array<ColorItemType>
numList: Array<NumItemType>
}
}
const request = () => {
return [{
itemId: 1,
type: 0,
itemInfo: {
colorList: [{
colorId: 1,
colorName: 'blue'
}],
numList: []
}
}];
};
const dataSource: Array<ResType> = request();
const formatData = dataSource.map(dataItem => {
const list: Array<ColorItemType | NumItemType> = dataItem.type === 1 ? dataItem.itemInfo.numList : dataItem.itemInfo.colorList;
return list.map(listItem => {
return {
// An error will be reported here
value: listItem.numId || listItem.colorId,
label: listItem.numName || listItem.colorName
};
});
});
Masalahnya di sini adalah karena
B
tidak mendeklarasikan propertia
, mungkin pada saat run-time memiliki propertia
dari jenis yang mungkin (karena Anda dapat menetapkan objek dengan set properti apa pun menjadiB
selama ia memiliki properti tipe stringb
). Anda dapat membuatnya bekerja secara eksplisit dengan mendeklarasikan propertia: undefined
diB
(dengan demikian memastikan bahwaB
tidak akan memiliki propertia
acak):type A = { a: string; } type B = { b: string; a: undefined } type AorB = A | B; declare const AorB: AorB; if (AorB.a) { // Ok }
Tidak bekerja untuk saya 07.10.2020
Dan menurut saya perilaku TS ini tidak baik karena tidak banyak membantu pengembang ...
Komentar yang paling membantu
saya menemukan solusi di buku:
Kutipan Dari: Basarat Ali Syed. “TypeScript Deep Dive.” Apple Books.
properti pada objek dan dapat digunakan sebagai pelindung tipe, dan TypeScript dapat mengetahui tipe yang Anda gunakan.