Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 05:08
    typescript-bot synchronize #41195
  • 01:30
    KilianKilmister edited #41227
  • 01:30
    KilianKilmister opened #41227
  • Oct 24 18:00
    typescript-bot closed #40111
  • Oct 24 16:10
    ahejlsberg synchronize #41218
  • Oct 24 16:10

    ahejlsberg on fix39947

    Use Ternary.Unknown to signal v… (compare)

  • Oct 24 16:03
    typescript-bot labeled #41226
  • Oct 24 16:03
    a-tarasyuk opened #41226
  • Oct 24 14:35
    whzx5byb opened #41225
  • Oct 24 07:28
    typescript-bot synchronize #41195
  • Oct 24 06:26
    github-actions[bot] synchronize #15575
  • Oct 24 06:26
    github-actions[bot] synchronize #28460
  • Oct 24 06:26
    github-actions[bot] synchronize #31641
  • Oct 24 06:25

    github-actions[bot] on master

    Update package-lock.json (compare)

  • Oct 24 05:02
    typescript-bot synchronize #41195
  • Oct 24 03:54
    xenoterracide edited #41224
  • Oct 24 03:53
    xenoterracide edited #41224
  • Oct 24 03:48
    xenoterracide edited #41224
  • Oct 24 03:47
    xenoterracide opened #41224
  • Oct 24 01:35
    typescript-bot synchronize #41195
AnyhowStep
@AnyhowStep
I'm taking a domestic flight and the flight number starts with "TS". I just found it funny I can't escape TS
I hope the flight software wasn't written with Typescript
webstrand
@webstrand
Are you on Air Transat?
TSC931? Or am I barking up the wrong tree. I've never used flight trackers before
AnyhowStep
@AnyhowStep
Yeah air transat. I like how it's either TS or TSC. Both are Typescript related
I'm not telling which =P
But there aren't many flights at all. Airport is very empty
webstrand
@webstrand
There are so few flights it's shocking
hope your flight isn't too uncomfortable
AnyhowStep
@AnyhowStep
Thanks, I'm sure it'll be fine. Imagine a flight so quiet and empty, without kids or babies
webstrand
@webstrand
I've seen some horrible photos of airplanes packed to the seams, since there are so few flights right now
AnyhowStep
@AnyhowStep
That would be a fucking nightmare
webstrand
@webstrand
'course I always fly economy
AnyhowStep
@AnyhowStep
There's no one at my gate, at the moment. But we're not close to boarding time yet. Same. Economy all the way. Ain't got money for anything else
Salathiel Genèse
@SalathielGenese
I'm still alive, Keith. It won't change soon, eventually.
I hope you.re doing better.
habibaatify
@habibatify_twitter
interface Item {
    name: string;
    quantity?: number;
}

interface ItemConstructor {
    new( name: string, quantity: number): Item;
}

let itemConstructor: ItemConstructor = class {
    name!: string;
    constructor(name: string/**, quantity: number**/) {}
    //                      ^^^^^^^^^^^^^^^^^^^^^^^^
    // I expected an error because the required "quantity" parameter is missing
    // So this should not be assignable to itemConstructor...
    //
    // What am I missing
}
Keith Layne
@keithlayne

Here's a short example that shows basically the same concept:

type Foo = (a: string, b: number) => void;
const foo: Foo = (a) => {};

This is not an error. If you had a concrete class and passed too many args that would be an error, but in terms of function types, functions with fewer args are assignable. This is how JS works - if you pass too many args they are just ignored.

Aaron Beall
@aaronbeall

I know I've asked this before... is there a way to define a map type with specific keys? Like

type Foo = { a: string; b: string; c: string };
const config: Record<K extends keyof Foo, boolean> = {
  a: true,
  c: false
}
// typeof config = { a: boolean; c: boolean };

I know I can create a superfluous function to create the object with an inferred type

Aaron Beall
@aaronbeall

I came up with

const SubRecord = <K extends keyof any, T>() => 
  <SubK extends K>(obj: Record<SubK, T>) => 
    obj;

const config = SubRecord<keyof Foo, boolean>()({
  a: true,
  c: false
});

Is there a way that doesn't require a superfluous function?

webstrand
@webstrand
Nope, unfortunately.
If you put a type on the variable, the type of the variable will not be inferred from assignment even when the assignment is narrower
I use recast in my own build chain to remove stub functions.
But that's outside of typescript
webstrand
@webstrand
(It's just a simple rewrite from a const x = Narrow<{ a: string }>()({ a: "foo" } as const) to const x = { a: "foo" } after type checking is complete)
Reko Tiira
@rekotiira

This is a bit difficult to describe, but I have a bit of an issue and I'm not sure how to solve this, or is it even solvable in the first place. I have tried to make a simplified test-case..

I have a function test that takes 2 arguments, an object of type Wrapped<T> and a function that as argument takes type T. So basically something like:

type Fn<T> = (arg: T) => void;
declare const test: <T>(wrapped: Wrapped<T>, fn: Fn<T>) => void;

TS allows me to use test with an anonymous function and it infers the argument type nicely, eg, this works:

type Wrapped<T> = { value: T };
declare const foo: Wrapped<string>;
test(foo, (arg) => { /* ... */ }); // TS infers arg as string, which is what I want

Now let's say I instead have an union type inside the Wrapped Wrapped<string | undefined>. I then have a function that only takes a string as an argument. This will produce an error as expected:

declare const strFunc: (arg: string) => void;
declare const foo: Wrapped<string | undefined>;
test(foo, (arg) => strFunc(arg)); // ERROR: string | undefined is not assignable to string

But if I give strFunc directly as an argument to test without the anonymous function wrapping the call, then TS does not complain, i.e.:

declare const strFunc(arg: string);
declare const foo: Wrapped<string | undefined>;
test(foo, strFunc); // NO ERROR

I know the reason is because the strFunc has a narrower type than the Fn<string | undefined>, so it's assignable. But for my purposes I would like that case to give an error. I know I can fix it by inferring the inner type for the Wrapped from the function's parameter instead, but that breaks the usage of anonymous function, i.e.:

declare const test: <T extends (...args: any[]) => any>(
  wrapped: Wrapped<Parameters<T>[0]>,
  fn: T
) => void;
test(foo, strFunc); // ERROR: string | undefined is not assignable to string
test(foo, (arg) => strFunc(arg)); // inferring no longer works, arg is now any

So my question is, is there a way to make it so that both of these cases work at the same time? I've been banging my head to the wall for quite a while with this, but I haven't figured it out.

webstrand
@webstrand
@rekotiira This should do what you want:
export type NoInfer<T> = T & {[K in keyof T]: T[K]};
declare function test<T>(wrapped: Wrapped<T>, fn: (arg: NoInfer<T>) => void): void;
A bit more info about various NoInfer implementations: https://github.com/microsoft/TypeScript/issues/14829#issuecomment-520191642
Reko Tiira
@rekotiira

@webstrand that doesn't work. It'll just infer the type from the Wrapped<T>, which means T is inferred as string | undefined, which means the 2nd argument is going to be fn: (arg: NoInfer<string | undefined>) => void.

(arg: string) => void is assignable to (arg: NoInfer<string | undefined>) => void, so you won't get an error when you do test(foo, strFunc)

webstrand
@webstrand
@rekotiira I'm not clear on what's wrong, here's a demo which one one those the wrong?
Reko Tiira
@rekotiira
Hmm that's weird. I put that exact code in my VSCode and I'm not seeing an error.
webstrand
@webstrand
are you using strict?
Reko Tiira
@rekotiira
yep
webstrand
@webstrand
same version of tsc, or a different one?
Reko Tiira
@rekotiira
3.9.7
webstrand
@webstrand
huh
Does it catch the error when using tsc outside of vscode?
Reko Tiira
@rekotiira
let's try
still no error
hmm actually it seems that our tsconfig.json only has alwaysStrict set to true, but not strict
webstrand
@webstrand
ah "alwaysStrict" is just for added "use strict" to every file
Reko Tiira
@rekotiira
yeah seems so
webstrand
@webstrand
strict is the one that provides additional type safety
NoInfer doesn't work without strictNullChecks (which is implied by strict)
Reko Tiira
@rekotiira
seems like enabling produces quite a bit of errors in our project's codebase :D but I think it's probably going to be a good idea to go through these and fix them
webstrand
@webstrand
yeah, I really, really recommend using strict
Reko Tiira
@rekotiira
well strictNullChecks we actually do have set to true explicitly
could it be the strictFunctionTypes that does the magic?
webstrand
@webstrand
oh yeah, that's the one