第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

使用 Exclude 和 | 時(shí)鑒別器未按預(yù)期工作

使用 Exclude 和 | 時(shí)鑒別器未按預(yù)期工作

楊__羊羊 2022-07-01 16:08:02
我不太知道如何表達(dá)這個(gè)問(wèn)題,但我偶然發(fā)現(xiàn)了一個(gè)特殊的問(wèn)題。我試圖Thingy通過(guò)使用foo類型為Kind.interface AKind {    kind: 'A';}interface BKind {    kind: 'B';}interface CKind {    kind: 'C';}type Kind = AKind | BKind | CKind;type ExCThingy = {    foo: Exclude<Kind, CKind>,    something: 'test';}type CThingy = {    foo: CKind,    somethingelse: 'test2';}type Foo = {    foo: Kind}function DoSomething(args: ExCThingy | CThingy) {    function isCThingy(args: ExCThingy | CThingy): args is CThingy {        return args.foo.kind === 'C';    }    if (isCThingy(args)) {        //Do C thing        return;    }    //else Do ExC thing    return;}const a: AKind = {    kind: 'A',}const b: BKind = {    kind: 'B',}const c: CKind = {    kind: 'C',}const fooArray: Foo[] = [{    foo: a,},{    foo: b,},{    foo: c,    }];fooArray.map(e => DoSomething({    foo: e.foo,    something: 'test',    somethingelse: 'test2'}));ts 編譯器抱怨:Argument of type '{ foo: Kind; something: "test"; somethingelse: "test2"; }' is not assignable to parameter of type 'ExCThingy | CThingy'.  Type '{ foo: Kind; something: "test"; somethingelse: "test2"; }' is not assignable to type 'CThingy'.    Types of property 'foo' are incompatible.      Type 'Kind' is not assignable to type 'CKind'.        Type 'AKind' is not assignable to type 'CKind'.          Types of property 'kind' are incompatible.            Type '"A"' is not assignable to type '"C"'.(2345)
查看完整描述

1 回答

?
翻閱古今

TA貢獻(xiàn)1780條經(jīng)驗(yàn) 獲得超5個(gè)贊

有幾件事導(dǎo)致這種情況發(fā)生。這里的主要問(wèn)題是 TypeScript 不支持嵌套的可區(qū)分聯(lián)合。在microsoft/TypeScript#18758有一個(gè)相當(dāng)古老的開(kāi)放建議;如果您對(duì)此非常關(guān)心,您可能想去那里給它一個(gè)??,或者如果它特別引人注目,請(qǐng)描述您的用例。不過(guò),就目前而言,它還不是語(yǔ)言的一部分。這意味著,這樣的代碼會(huì)成功:


type Discrim = { a: 0, c: string } | { a: 1, c: number };

declare const d: Discrim;

d.a === 0 ? d.c.toUpperCase() : d.c.toFixed(); // okay

但是這樣的代碼失敗了:


type NestedDiscrim = { a: { b: 0 }, c: string } | { a: { b: 1 }, c: number };

declare const n: NestedDiscrim;

n.a.b === 0 ? n.c.toUpperCase() : n.c.toFixed(); // error!

因?yàn)樵谇罢咧?,Discrim編譯器將其視為帶有a屬性作為判別式的可區(qū)分聯(lián)合,但在后者中,NestedDiscrim不將其視為帶有a屬性作為判別式的可區(qū)分聯(lián)合。


同樣,在您的情況下,Kind是受歧視的工會(huì),但ExCThingy | CThingy不是。


對(duì)于編譯器視為可區(qū)分聯(lián)合的類型,從 TypeScript 3.5 開(kāi)始,添加了對(duì)如下賦值的支持:


const k: Kind = { kind: Math.random() < 0.5 ? "A" : Math.random() < 0.5 ? "B" : "C" }; // okay

分配給的對(duì)象的k類型{kind: "A" | "B" | "C"}在技術(shù)上不可分配給受歧視聯(lián)合的任何單個(gè)成員Kind,這是您在 TS3.4 及以下版本中遇到的錯(cuò)誤:


// Type '{ kind: "A" | "B" | "C"; }' is not assignable to type 'Kind'.

但是在 TS3.5 及更高版本中,編譯器會(huì)進(jìn)行額外的檢查以獲取具有聯(lián)合類型判別屬性的單個(gè)對(duì)象類型,并將聯(lián)合向上傳播到具有單類型判別屬性的對(duì)象類型的聯(lián)合中。這樣就可以編譯了。


不幸的是,正如我們所提到的,ExCThingy | CThingy根據(jù)編譯器,它不是一個(gè)有區(qū)別的聯(lián)合。上述支持僅適用于受歧視的工會(huì)。對(duì)于非歧視工會(huì),你會(huì)得到同樣的錯(cuò)誤:


type NotDiscrim = { a: string } | { a: number };

const x: NotDiscrim = { a: Math.random() < 0.5 ? "" : 1 }; // error in all versions of TS

// Type '{ a: string | number; }' is not assignable to type 'NotDiscrim'

編譯器根本不對(duì)非區(qū)分聯(lián)合執(zhí)行聯(lián)合傳播分析。并且由于ExCThingy | CThingy不被認(rèn)為是有區(qū)別的聯(lián)合,因此 type 的值{ foo: Kind, something: 'test', somethingelse: 'test2' }不被認(rèn)為是 type ExCThingy | CThingy。


所以這就是正在發(fā)生的事情。要在此處繼續(xù),您可能需要使用類型斷言來(lái)告訴編譯器您確定您正在做的事情是安全的:


fooArray.map(e => DoSomething({

    foo: e.foo,

    something: 'test',

    somethingelse: 'test2'

} as ExCThingy | CThingy)); // no error

要么,要么將單個(gè)對(duì)象拆分為編譯器可以實(shí)際檢查的聯(lián)合,如下所示:


fooArray.map(e => DoSomething(e.foo.kind === "C" ?

    { foo: e.foo, somethingelse: 'test2' } : { foo: e.foo, something: 'test' }

));


查看完整回答
反對(duì) 回復(fù) 2022-07-01
  • 1 回答
  • 0 關(guān)注
  • 131 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)