21 Matching Annotations
  1. Feb 2023
    1. If you want a workaround for the case where you can't just replace key with a string literal, you could write your own user-defined type guard function called hasProp(obj, prop). The implementation would just return prop in obj, but its type signature explicitly says that a true result should cause obj to be narrowed to just those union members with a key of type prop: function hasProp<T extends object, K extends PropertyKey>( obj: T, prop: K ): obj is Extract<T, { [P in K]?: any }> { return prop in obj; } and then in your function, replace key in a with hasProp(a, key): function f3(a: A) { const key = 'b'; if (hasProp(a, key)) { return a[key]; // okay } return 42; }
  2. Aug 2021
    1. function strictIsDog<T extends Dog extends T ? unknown : never>( // like <T super Dog> candidate: Dog | T // if Dog extends T then Dog | T is T ): candidate is Dog { // compiler recognizes that Dog | T can narrow to T return "bark" in candidate; } if (strictIsDog(animal)) {} // okay if (strictIsDog(dog)) {} // okay if (strictIsDog(mixed)) {} // okay if (strictIsDog(cat)) {} // error! // ~~~ <-- Cat is not assignable to Dog
    2. Using the second type guard forces the user to write a more precise type and therefore manifest any nonsensical type guards that produce never, like: function silly<T extends number>(candidate: T): candidate is T & boolean { … }
    1. function isKeyOfMcuParams(x: string): x is keyof McuParams { switch (x) { case 'foo': case 'bar': case 'baz': return true; default: return false; } }
    2. Is it possible to write a user defined type guard for a keyof string type such as keyOf foo when foo is defined ONLY as a type (and not in an array)?
    1. It means that when having a type guard:TypeScript and JavaScript runtime are tied to the same behaviour.
    2. Inside the if statement, TypeScript will assume that amount cannot be anything else than a string, which is true also at the runtime thanks to typeof JavaScript operator.
    3. This “gap” between what we call “runtime” and “static analysis” can be filled using TypeScript Type Guards.
    1. we use a type guard here to say that, if this function returns true, any further usage of key will be of the specified type. Otherwise, it's still just a string.
    1. Adding to the accepted answer, if you happen to need to use a type guard against a mixin, you'll get this error too, since the is operator doesn't behave as an implements would.
    2. Regarding the error message, the predicate type must be assignable to the value type because the type guard is used to check whether a value with a less-specific type is in fact a value with a more-specific type. For example, consider this guard: function isApe(value: Animal): value is Ape { return /* ... */ } Ape is assignable to Animal, but not vice versa.
    3. If there is no relationship between the value's type and the type in the type predicate, the guard would make no sense. For example, TypeScript won't allow a user-defined guard like this: function isString(value: Date): value is string { return typeof value === "string"; }
  3. Oct 2019
    1. These typeof type guards are recognized in two different forms: typeof v === "typename" and typeof v !== "typename", where "typename" must be "number", "string", "boolean", or "symbol". While TypeScript won’t stop you from comparing to other strings, the language won’t recognize those expressions as type guards.
    2. Type Guards