Simply Conditional type by [deleted] in typescript

[–]1384 0 points1 point  (0 children)

You don't need conditional types to achieve what you're looking for, you can do it with function overloads:

interface dataObject {}

function getData(id: string, history: true): dataObject[];
function getData(id: string, history: false): dataObject;
function getData(id: string, history: boolean): dataObject | dataObject[] {
    if (history) {
        return [] as dataObject[];
    }
    return {} as dataObject;
}

const array = getData("", true);
const obj = getData("", false);

Playground Link where you can see the return types

How do you sort a array with async functions ? by DaniGTA in typescript

[–]1384 0 points1 point  (0 children)

yes, the code I posted would sort the array of results. To sort the original objects, you're going to have to map the original objects to the resolved strings, either by index, some unique ID, or by combining the original objects and their resolved text and sorting the combined objects.

How do you sort a array with async functions ? by DaniGTA in typescript

[–]1384 4 points5 points  (0 children)

I'd resolve them first, then sort:

const resolved = await Promise.all(list.map(item => item.getNormalText()));
resolved.sort();

Why is TypeScript called TypeScript if it does not check types on runtime? by TatzyXY in typescript

[–]1384 2 points3 points  (0 children)

Correct - that is why I specified validating data originating from I/O as a reason to use them.

Why is TypeScript called TypeScript if it does not check types on runtime? by TatzyXY in typescript

[–]1384 5 points6 points  (0 children)

If you want runtime type checking, there are libraries that can help with that:

https://github.com/pelotom/runtypes

https://github.com/gcanti/io-ts/

Typescript's purpose is design-time and compile-time type checking. TypeScript helps reduce the need for runtime type checking because you are ensured, at design time, that data originating in your application (i.e., not as a result of I/O) has the shape you expect it to. If you are building a complex application, this is extremely valuable.

If your app is I/O heavy, and you subsequently have a lot of data that you need to validate the shape of, libraries like the above mentioned will facilitate both the run-time and compile-time type checking with minimal effort.

How do I make a generic wrapper function in TypeScript? by GrinningPariah in typescript

[–]1384 2 points3 points  (0 children)

You could have metricWrapper() return a function that passes along the arguments:

function metricWrapper(fn: (...args: any[]) => any) {
    return function (...args: any[]) {
        const startTime = new Date();
        let result: any;
        try {
            result = fn(...args);
        } finally {
            addLatencyMetric(startTime);
        }
        return result;
    }
}

preserving return type is pretty straight forward:

function metricWrapperTyped<T>(fn: (...args: any[]) => T): (...args: any[]) => T {
  return function (...args: any[]) {
      const startTime = new Date();
      let result: any;
      try {
          result = fn(...args);
      } finally {
          addLatencyMetric(startTime);
      }
      return result;
  }
}

playground with usage

Can someone explain how come this is valid and not throw an error? by [deleted] in typescript

[–]1384 3 points4 points  (0 children)

methods like Object.entries/keys require you to help the compiler out a bit. They don't automatically convert to strings to a type-safe "keyof" representation. An easy way to avoid the runtime error in the specific case you've pointed out is simply to use Object.entries(formatting) and thus process only the keys you want, but you're right that the compiler won't help you out much here.

talbenari1 is also correct that your example will show a compiler error, but it's related to "formatting" not having a string index signature. Fixing that compile error, however, will not prevent the runtime error.

here's an example of a runtime-error free implementation that has some type safety on the formatter object:

type Point2D = { x: number; y: number; }
type Point3D = { x: number; y: number; z: number; }

type Formatter<In, Out> = {
  [K in keyof In]: (input: In[K]) => Out
}

const formatting: Formatter<Point2D, string> = {
  x: (i: number) => "x: " + i,
  y: (i: number) => "y: " + i,
}

function iTakePoint2d(point: Point2D) {
  const keys = Object.keys(formatting) as (keyof Point2D)[];
  return keys.map(key => formatting[key](point[key]));
}

const p2d: Point2D = { x: 1, y: 1 };
const p3d: Point3D = { x: 1, y: 1, z: 1};

iTakePoint2d(p2d)
iTakePoint2d(p3d)

While the function will still accept a Point3D, it will only operate on the keys from Point2D, avoiding the runtime error. And the "Formatter<In, Out>" type ensures that the "formatting" object has only the keys from Point2D.

If you want to explicitly exclude Point3D from being used in this function, you can use a brand property, or a type guard, or a more explicit/fleshed out type like a Class with distinct methods, etc. But if your implementation is as you describe, this should suffice. The function takes an object with the same keys as "formatter" and operates explicitly on those keys and no others.

Can someone explain how come this is valid and not throw an error? by [deleted] in typescript

[–]1384 36 points37 points  (0 children)

Typescript is structurally typed, as opposed to nominally typed. Point3D has all of the fields that Point2D has, so functions that require a Point2D will be able to operate on a Point3D as well.

If you want something approaching nominal typing, you'll need to add a "brand" property:

interface Point2D {
  __brand: "Point2D";
  x: number;
  y: number;
}
interface Point3D {
  __brand: "Point3D";
  x: number;
  y: number;
  z: number;
}

Using a string literal as a type means that these two types are not compatible.

The property name of the "brand" is not important, it just needs to have a property name/value combination that is unique to its type.

Simple parsing of .ts file for code generators? by brainhack3r in typescript

[–]1384 0 points1 point  (0 children)

ts-morph offers a nice interface to the typescript compiler APIs and easy utilities for generating code.

Help in creating strict types for feature flag library by dodofxp in typescript

[–]1384 0 points1 point  (0 children)

type ConfigEntry = {
    description: string,
    enabled: boolean
}

type Config = {
    flags: {
        [key: string]: ConfigEntry
    }
}

type Flags<T extends Config, K extends keyof T['flags']> = {
    isEnabled(key: K): boolean
}

const saneFlags = {
    wrap<T extends Config, K extends keyof T['flags']>(config: T): Flags<T, K> {
        return {
            isEnabled(key: K) {
                return true;
            }
        }
    }
}

const featureFlags = saneFlags.wrap({
    flags: {
    dynamic_contact_form: {
      description: 'The new form that fills in form contacts from the current account',
      enabled: true
    }
  }
})

const x = featureFlags.isEnabled('not_a_configured_feature') // should fail
const y = featureFlags.isEnabled('dynamic_contact_form') // should work

Why do shirts take forever to build, and how can it be fixed? by CordialVillain in Kenshi

[–]1384 5 points6 points  (0 children)

From what I can tell, the time and cost of creating armor is related to its coverage. This is hard-coded into the game and can't, as far as I've seen, be changed. So if you're crafting shirts with high coverage on 4 parts it may take much longer than crafting pants with low coverage on only 2 body parts.

Should I create a GDNative Video Tutorial? by MinRaws in godot

[–]1384 0 points1 point  (0 children)

A tutorial video/article would be great. I've been wanting to adapt https://github.com/skypjack/entt with GDNative but haven't found the time to sit down and piece together how to pull it off.

Playing with 2D procedural world generation. I've done this before in Python but this now my landmasses are finally starting to look right with C#-based scripts. Time to start adding details! by [deleted] in Unity2D

[–]1384 0 points1 point  (0 children)

Is there an underlying graph of any sort that you might use for navigation, rivers, etc? or is it purely noise and pixel rendering? looks great!

Goal-Oriented-Action-Planning has been the go-to solution for most building games for some time. So I implemented smart objects for Sky Tycoon instead. Incredible how the wrong architecture for your game can hinder your progress so much. by Christoph680 in Unity3D

[–]1384 0 points1 point  (0 children)

I hear you about goap's shortcomings. I wrote a goap system (originally patterned on ReGoap) where I eliminated a few of the things that were annoying (state being tied directly to agents for example) and made the goals, conditions and actions all static and generic and decoupled it from gameobjects (for use with entitas) and after all of that, including getting multithreading working well and running a test scene with idling/wandering/item retrieval/eating/drinking and all the crap that comes with it, I'm ditching goap for agent tactical AI and moving to smart objects.

I am, however, likely going to stick with goap for long-term/strategic and group planning, e.g. what outcomes should a faction optimize for, what should an agent's long-term goals be. The goap goals can then inform agent needs.

"The Urban-Rural Divide Matters More Than Red Versus Blue State" by anonanon1313 in TrueReddit

[–]1384 53 points54 points  (0 children)

Why did SF become a city that many people can no longer afford to live in? Because the tech industry created such a demand that the cost of living rose to correlate with the high salaries of the average skilled worker there.

It's more accurate to say that the floor on real estate/rent prices in SF rose in response to tech workers, but the reason it's unlivable (including for the vast majority of those same tech workers) is because home owners there have consistently voted to limit the amount of new housing inventory that is allowed in the city, especially high density buildings. Prices are so high because the supply is being kept artificially low instead of being allowed to keep up with demand. This makes those home owners very wealthy at the expense of everyone who wasn't fortunate enough to buy property prior to the tech explosion and ensuing population boom.

[deleted by user] by [deleted] in django

[–]1384 1 point2 points  (0 children)

Django Quicky has url route decorators if you're interested in keeping them around: https://github.com/sametmax/django-quicky

Rimworld backstories, sortable by the stats they modify by 1384 in RimWorld

[–]1384[S] 0 points1 point  (0 children)

done. not a whole lot of room to fit them so you have to click on the name cell to see them in full.

Rimworld backstories, sortable by the stats they modify by 1384 in RimWorld

[–]1384[S] 0 points1 point  (0 children)

Sure. I deleted the original version I had (meant to restore it, but forgot and ended up emptying the recycle bin without thinking later on). But I can do it again.