Created
November 22, 2022 12:26
-
-
Save nilshartmann/53f74fa10dbb6a4145601f57988b7933 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default undefined; | |
type Container<T> = { | |
consume: (arg: T) => void; | |
}; | |
// string ist super-type von "hello" 😳 | |
// Entspricht in C# sowas hier: | |
// public class Event { } // => string | |
// public class MouseEvent : Event { } // => "hello" | |
type StringType = string; | |
type HelloType = "hello"; | |
let superType: StringType = "irgendwas"; | |
let subType: HelloType = "hello"; | |
// Dem allgemeinen Typen kann in eine spezialisierung zu weisen! | |
// alles was auf subType definiert ist, muss ja auch in supertype vorhanden sein | |
superType = subType; // ok | |
// dem SPEZIALISIERTEN Typen kann ich aber nicht den allgemeinen zuweisen | |
// (das ist wie in OO-Sprachen), denn im SPEZIALISIERTEN erwarte ich ja | |
// eigene bzw. mehr/andere Eigenschaften, die im ALLGEMEINEN (super) Type möglicherweise | |
// nicht vorhanden sind | |
subType = superType; // error | |
let containerWithString: Container<StringType> = { | |
// string | |
consume: arg => {} | |
}; | |
containerWithString.consume("OK"); // OK => beliebiger string | |
containerWithString.consume("hello"); // OK => spezialisierter string | |
let containerWithHello: Container<HelloType> = { | |
// "hello" | |
consume: arg => {} | |
}; | |
containerWithHello.consume("OK"); // FEHLER => beliebiger string | |
containerWithHello.consume("hello"); // OK => spezialisierter string | |
// Hier kann ich den SPEZIALISIERTEN Typen ('hello') NICHT | |
// an den ALLGEMEINEN Typen ("") zuweisen. | |
// Wenn das FUNKTIONIEREN WÜRDE, könnten wir plötzlich containerWitHello | |
// mit jedem beliebigen String aufrufen | |
containerWithString = containerWithHello; // error | |
containerWithString.consume("xxx"); // wenn Zeile davor gehen würde => 💥 | |
// Dem spezialisierten Typ wird der ALLGEMEINE Typ zugewiesen | |
// DAS wiederrum geht hier, denn wir können nun containerWitHello | |
// nur mit "hello" aufrufen, und damit kommen beide Typen klar | |
containerWithHello = containerWithString; // ok | |
containerWithHello.consume("hello"); | |
containerWithHello.consume("..."); // FEHLER | |
// Functions are contravariant in their parameter types, | |
// so unions of functions correspond to intersections | |
// of function parameters, and vice versa. | |
type Callback<T> = (value: T) => void; | |
type StringCallback = Callback<string>; | |
const stringCallbackFn: StringCallback = value => {}; | |
stringCallbackFn("something"); | |
stringCallbackFn(""); | |
type HelloCallback = Callback<"hello">; | |
const helloCallbackFn: HelloCallback = value => {}; | |
helloCallbackFn("something"); // nope | |
helloCallbackFn("hello"); // of course | |
type X = string & ""; | |
const x: X = ""; // OK | |
const xx: X = "falsch"; // nö... | |
function runCallback(callback: StringCallback | HelloCallback) { | |
// Ich muss ALLE eigenschaften von Callback beim Aufrufen | |
// berücksichtigen! | |
callback("hello"); // SUB type !!! | |
callback("nope"); // SUPER TYPE! | |
} | |
type NumberCallback = Callback<number>; | |
const numberCallbackFn: NumberCallback = value => {}; | |
numberCallbackFn("something"); // nope | |
numberCallbackFn(123); // of course | |
function runCallbackWithNumberAndString(callback: StringCallback | NumberCallback) { | |
// Ich muss ALLE eigenschaften von Callback beim Aufrufen | |
// berücksichtigen! | |
// => Das ist hier unmöglich | |
callback(1); // Schade... | |
callback("nope"); // Auch schade | |
} | |
function doSomething(x: string | number) { | |
// GEHT BEIDES... hier UNION TYPE! | |
x = 3; | |
x = "hallo"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment