Typescript: Der Schnittpunkt zweier generischer Parameter zu einem dritten wird nicht als äquivalent erkannt

Erstellt am 13. Jan. 2019  ·  3Kommentare  ·  Quelle: microsoft/TypeScript


TypeScript-Version: 3.3.0-dev.201xxxxx


Suchbegriffe:

Schnittpunkt von Generika

Code

let connect = <R1,R2, R = R1&R2 >(mapState2Props: (state) => R1, mapDispatch2Props: (dispatch: any) => R2): R => {
  let state = {};
  let dispatch = () => { };
  return { ...mapState2Props(state), ...mapDispatch2Props(dispatch)}
}

Erwartetes Verhalten:
Ich würde erwarten, dass dies gültig ist, da ich R = R1&R2 in der generischen Signatur definiert habe.

Tatsächliches Verhalten:

Erhalten Sie einen Fehler Type 'R1 & R2' is not assignable to type 'R'. auf der return-Anweisung. Ich habe auch R extends R1&R2 ausprobiert und erhalte den gleichen Fehler.

Spielplatz Link:

Verknüpfung

Verwandte Themen:

https://github.com/Microsoft/TypeScript/issues/5823

Question

Hilfreichster Kommentar

Ich glaube, der Fehler ist hier richtig. Ja, R1 & R2 dem Standardwert von R zugewiesen werden, aber R kann mit einem _mehr_ spezifischen Typ instanziiert werden. Betrachten Sie die folgende Instanziierung.

connect<{ x: number; }, { y: number; }, { x: number, y: number, z: number }>( ... );

Dies ist eine gültige Instanziierung von R1 , R2 und R , aber R1 & R2 _nicht R zugewiesen werden, da das fehlt z Parameter.

In Ihrem Beispiel ist der Parameter R nicht erforderlich (obwohl Ihr tatsächlicher Anwendungsfall möglicherweise komplizierter ist). Das funktioniert:

let connect = <R1,R2>(mapState2Props: (state) => R1, mapDispatch2Props: (dispatch: any) => R2): R1 & R2 => {
  let state = {};
  let dispatch = () => { };
  return { ...mapState2Props(state), ...mapDispatch2Props(dispatch)}
}

Alle 3 Kommentare

Ich glaube, der Fehler ist hier richtig. Ja, R1 & R2 dem Standardwert von R zugewiesen werden, aber R kann mit einem _mehr_ spezifischen Typ instanziiert werden. Betrachten Sie die folgende Instanziierung.

connect<{ x: number; }, { y: number; }, { x: number, y: number, z: number }>( ... );

Dies ist eine gültige Instanziierung von R1 , R2 und R , aber R1 & R2 _nicht R zugewiesen werden, da das fehlt z Parameter.

In Ihrem Beispiel ist der Parameter R nicht erforderlich (obwohl Ihr tatsächlicher Anwendungsfall möglicherweise komplizierter ist). Das funktioniert:

let connect = <R1,R2>(mapState2Props: (state) => R1, mapDispatch2Props: (dispatch: any) => R2): R1 & R2 => {
  let state = {};
  let dispatch = () => { };
  return { ...mapState2Props(state), ...mapDispatch2Props(dispatch)}
}

hmm ya das ist ein guter Punkt. Das Ziel hier war es, irgendwann dahin zu gelangen, wo Sie einfach den Rückgabetyp R angeben und die Typensicherheit erhalten konnten, dass mapState2Props & mapDispatch2Props zusammen zu einem gültigen R Objekt.

Z.B:

interface IComponentProps{
  foo: string;
  doFoo: ()=>void
}
let props: IComponentProps = connect<IComponentProps>(
  (state) => { foo: state.foo },
  (dispatch) => {doFoo: () => dispatch('FOO')}
)

Allerdings ... ich bin mir nicht sicher, ob das überhaupt möglich ist ... Anscheinend müssten Sie stattdessen R1 & R2 als eine Teilmenge von R , aber sie sind voneinander abhängig ...

Beachten Sie, dass R auch ein völlig unabhängiger Typ sein kann. Standardtypargumente in Generika sind keine Einschränkungen.

connect<{ a: string }, { b: number }, { c: boolean[] }>(() => ({ a: "a" }), () => ({ b: 3 }))
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

Antony-Jones picture Antony-Jones  ·  3Kommentare

MartynasZilinskas picture MartynasZilinskas  ·  3Kommentare

kyasbal-1994 picture kyasbal-1994  ·  3Kommentare

DanielRosenwasser picture DanielRosenwasser  ·  3Kommentare

Roam-Cooper picture Roam-Cooper  ·  3Kommentare