/r/typescript

Photograph via snooOG

TypeScript is a language for application-scale JavaScript development.

TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.

Resources

Language

Discussion

Rules

  1. Your post should be typescript focused This is r/typescript, lets keep it on topic
  2. No general advertising, promoting services/libs with zero TS utility or closed source projects We get it, you people build awesome things, but this isn't r/sideproject, if you're posting a project it needs to be open source, you need to link to the repo and most importantly given that this is r/typescript it should not only be in typescript but be something that contributes to TS utility (Not just a random lib that happens to be written in TS). Also no general spam of other products or software, even if it's free. Exceptions can be made for software that will be exceptionally useful for typescript development and pipelines, but this is at the moderation teams discretion.
  3. Keep self promotion to a minimum. "It's perfectly fine to be a redditor with a website, it's not okay to be a website with a reddit account." - Confucius
  4. No Recruiters. or recruitment posts, we have a sticky for that, still, it's for redditors only, not professional recruiters.

/r/typescript

141,297 Subscribers

1

Is TypeScript + Rust a good stack?

Currently, I only work in TypeScript but I am very fond of learning low level optimizations and working in more type safe languages rather than using high level languages.

I will be learning rust regardless of any comments, but I was curious, what is the general opinion regarding this?

Using Typescript for frontend (before anyone says just use javascript, I don't want to) and Rust for backend?

I understand it will also require the knowledge and use of wasm, correct?

Thoughts please.

7 Comments
2024/12/03
06:48 UTC

0

Our backend is switching from C# to TypeScript. I like TypeScript in theory, but it seems so unreadable. Help?

I love C#. It’s one of those languages that feels elegant and expressive, almost like writing in English. Two of my favorite features are LINQ and extension methods, which make code not only functional but also a pleasure to read.

For example, in C#, you can write something like this:

var result = data.GetProcessedData()
                 .Transform()
                 .LogResults();

It reads just like a sentence. Every method does something meaningful, and the flow of data is clear at a glance.

Recently, though, my work decided to move our backend to TypeScript, and I’m struggling to replicate this level of clarity and fluency. Here's how something similar would look in TypeScript using RxJS:

this.data$ = this.service.getData()
    .pipe(
        switchMap(data => this.service.processData(data)),
        map(result => this.transformResult(result)),
        tap(finalResult => this.logResults(finalResult))
    );

Does anyone have any advice on how to make RxJS or TypeScript more readable and fluent?

I'm also looking for a way to write domain-specific abstractions or extensions in TypeScript that simplify repetitive RxJS patterns.

Since I just started this job, and the job market is weird, and I live in a weird place where tech doesn't pay very well, and I have family nearby, I don't have very strong expectations about working with the language I like and find easy to read.

So I'd love to hear if you know of any libraries, patterns or tricks that can make TypeScript backend development more enjoyable. IDEs, welcome too.

19 Comments
2024/12/03
06:31 UTC

0

How do you launch a typescript coded website based on Babylon js?

Please give detailed instructions. Thank you in advance.

3 Comments
2024/12/03
03:53 UTC

6

TypeScript Testing: Should I run tests against TS or compiled JS?

I'm struggling with TypeScript testing configuration in a Node.js project and looking for advice on best practices, especially around whether to run tests against TS directly or compiled JS.

Current Setup

My Node.js/TypeScript testing environment:

// package.json (relevant dependencies)
{
  "devDependencies": {
    "@jest/globals": "^29.6.1",
    "@types/jest": "29.5.10",
    "jest": "^29.7.0",
    "jest-ts-webcompat-resolver": "^1.0.0",
    "ts-jest": "^29.1.1",
    "ts-node": "^10.9.2",
    "tsc-alias": "^1.8.8",
    "typescript": "5.4.5"
  }
}

Jest configuration:

// jest.config.ts
import { pathsToModuleNameMapper } from 'ts-jest'
import { compilerOptions } from './tsconfig.json'
import type { JestConfigWithTsJest } from 'ts-jest'

const config: JestConfigWithTsJest = {
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { 
    prefix: '<rootDir>/',
  }),
  preset: 'ts-jest',
  resolver: 'jest-ts-webcompat-resolver',
  collectCoverage: true,
  coverageReporters: ['json', 'html'],
}

export default config

TypeScript configuration:

// tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "~sourceService/*": ["src/services/source/*"],
      "~crawlService/*": ["src/services/crawl/*"],
      "~searchService/*": ["src/services/search/*"],
      "~/*": ["src/*"]
    },
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "target": "ES2022",
    "typeRoots": ["node_modules/@types", "src/@wboTypes"],
    "outDir": "dist",
    "rootDir": "./",
    "strict": true,
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true
  },
  "include": [
    "jest.config.ts",
    "./src/**/*",
    "./test/**/*",
    "private/counter.ts",
    "private/data.ts",
    "private/test.ts"
  ]
}

The Problem

I've been having constant issues with TypeScript + Jest configuration. Most recently, updating dependencies broke all tests, forcing me to pin TypeScript to version 5.4.5 to get things working again.

The Question

Given these ongoing configuration headaches, I'm considering a different approach:

  1. Write tests in TypeScript (keeping type safety during development)
  2. Compile everything to JavaScript (both source and test files)
  3. Run tests against the compiled JS

What I'd like to know:

  • What's the common practice in production TypeScript projects?
  • What are the trade-offs between running tests against TS vs compiled JS?
  • For those running larger TS codebases in production, how do you handle this?
  • Are there specific gotchas with either approach I should be aware of?

Edit: Using Node.js v18, if that matters.

6 Comments
2024/12/02
12:56 UTC

0

Advice for Clean Code in Javascript/TypeScript

I have an Interview Coding Round with Typescript Where the quality of the code will be checked How should i practice for this?
Any advice would be Appreciated..

5 Comments
2024/12/02
12:18 UTC

11

What project quality tools (or other useful tools) would you recommend for a Typescript package?

I have the obvious ones set up: prettier, eslint (I looked at some of the more recent linting tools and concluded they’re not ready), code coverage with istanbul. I’m looking into sonarqube but don’t know yet how useful it is. Using dependabot to keep dependencies up to date. Syncpack to make sure the dependencies across packages in the monorepo are in sync.

Considering lint-staged but I don’t like slowing down commits and would probably end up using --no-verify all the time.

What else, if anything, would you recommend? And are there better alternatives to anything I’ve listed?

15 Comments
2024/12/01
10:56 UTC

4

Who's hiring Typescript developers December

The monthly thread for people to post openings at their companies.

* Please state the job location and include the keywords REMOTE, INTERNS and/or VISA when the corresponding sort of candidate is welcome. When remote work is not an option, include ONSITE.

* Please only post if you personally are part of the hiring company—no recruiting firms or job boards **Please report recruiters or job boards**.

* Only one post per company.

* If it isn't a household name, explain what your company does. Sell it.

* Please add the company email that applications should be sent to, or the companies application web form/job posting (needless to say this should be on the company website, not a third party site).

Commenters: please don't reply to job posts to complain about something. It's off topic here.

Readers: please only email if you are personally interested in the job.

Posting top level comments that aren't job postings, [that's a paddlin](https://i.imgur.com/FxMKfnY.jpg)

0 Comments
2024/12/01
00:00 UTC

13

When creating an npm package, is it better to depend on things like lodash or copy paste / reimplement the bits you need?

Periodically I see an open source package announce they have “zero dependencies”, which definitely sounds great and reduces some of the uncertainty/worry of having to think about transitive dependencies.

But part of me can’t help but wonder how they achieved that “zero dependencies”. There are so many basic utilities that I would reach for a package for that I _could _ do my own implementation of but it’s just not worth it. Camelcase for eg has enough edge cases that I think it’s worth depending on something that does it well.

However, if the packages I want to depend on are stable and the amount of code I want to depend on is small, I could just copy paste it into my project? I get the good code and the package can have “zero dependencies”. This feels pretty horrible though.

All three options (depend/reimplement/copypaste) feel like they have some pretty big trade offs (and I’m not sure I’m keen on either of the “zero dependencies” versions). So I’m interested in what you think, as either a creator/maintainer or consumer of open source packages: how important is “zero dependencies” to you? Do you think it’s a good idea to copy code to achieve it?

44 Comments
2024/11/30
22:11 UTC

221

A goodie from TS 5.8

The next iteration of the compiler is going to be super exciting. Version 5.8 includes months of effort by Gabriela Britto, finalized in the PR #56941, to support conditional types and indexed access types in function return types.

At last, we can properly type functions like the one in the snippet without relying on dubious overloads or clunky, unreliable hacks.

https://preview.redd.it/bekp282cv34e1.png?width=1432&format=png&auto=webp&s=de10c5ecda958b1046ff625505a64abbe08a081f

Link to the PR

Link to the playground

P.S. If this gets merged, we ain't gonna need that default case anymore in this situation.

18 Comments
2024/11/30
21:27 UTC

1

Typescript official docs PDF/EPUB

Hi everyone,
I'm wondering if there's a PDF or EPUB version of the official documentation available. If anyone knows, please let me know!

Also, could you recommend any good advanced-level TypeScript books? I'd really appreciate your suggestions.

2 Comments
2024/11/30
18:14 UTC

3

Need help with a Type or Interface

Maybe someone can help me. I have a lot of classes that should have these two functions. One is dynamic, the other static. So I wanted to define a type or an interface, that describes that. But I wasn't able to solve that problem.

type TMyType = {
   // whatever
}

export class MyClass {
  toObject(): TMyType {
    throw new Error("Method not implemented.");
  }
  static fromObject(object: TMyType): Promise<MyClass> {
    throw new Error("Method not implemented.");
  }
}
2 Comments
2024/11/29
14:21 UTC

0

How do I even run a TypeScript project?

For JavaScript in node, I can usually do npm init, maybe install nodemon as a dev dependency, and get actually coding.

For TypeScript, if I look into its website, I'm pointed towards either "trying" it in the web browser, which is of zero productivity and unrealistic to a real development environment, or simply running tsc, which isn't quite very helpful at all.

I then search around and find out about ts-node, which has its own set of problems in practice, and then I try to stick with nodemon; it does seem to run TS code correctly, but with some libraries I get problems about ESM modules or something; I'm directed towards using "type": "module" in my package.json, but now nodemon doesn't recognize ".ts" files. I'm also directed towards putting some options in my tsconfig file, but there doesn't seem to be a single authoritative source on what options I should put in it if I were to start a new project. It always involves trial and error.

So I suppose my question is: is there a *single*, *authoritative* way to create and run a TypeScript project? Shouldn't it be in the official documentation? I feel that for all the promotion the language gets, in my experience it's extremely complicated to get to run, reminding me of having to configure webpack + babel stuff before vite existed for frontend JavaScript. I just want to type something like "run-typescript myfile.ts" and have something actually run my code, transparently of whatever process is used to get there, with hot reload. I'd just like to do programming, not configuring. Sorry for the rant kinda tone, but I'm very frustrated with this.

25 Comments
2024/11/29
07:25 UTC

17

How to disable class typing for plain objects

I've been using Typescript professionally for many years but I just discovered a "feature" that I hate - that I can do this:

class Myclass { foo: string }

const myObj: Myclass = { foo: "bar" }

myObj has no business being identifiable as Myclass. instanceof will fail, constructor lookups will fail, and if I define any methods or anything else in the prototype, these will be inaccessible (at least the last one will cause a compile error I believe).

I'm wondering if there's a secret compiler flag I can use to disable this, so that only objects created with the class's constructor can use the type.

54 Comments
2024/11/28
15:47 UTC

3

Mapped type inferred as union

Hi!

This got me scratching my head as in principle it sounds simple; if I have these types:

type SourceType = 'article' | 'video';

interface DBArticle {
  article: true;
}

interface DBVideo {
  video: true;
}

type DBAssetMap = {
  article: DBArticle,
  video: DBVideo
}

I wanted to write a function like this:

const test = <T extends SourceType>(assetType: T, asset: DBAssetMap[T]) => {...};

so that when assetType is article, asset would be a DBArticle, however asset is being inferred as a DBArticle | DBVideo union.

I've tried several incantations, including distributive conditional types, without luck.

Any help will be greatly appreciated!

5 Comments
2024/11/28
12:32 UTC

5

Can I declare types for a module that doesn't actually exist?

Essentially in the typescript playground, I want to declare types coming from a module.

I tried using "declare module" but it doesn't want to work for a module that doesn't actually exists and just gives this error: Cannot find module 'foo' or its corresponding type declarations.(2307)

Here's the playground code that I want to make work:

declare module "foo" {
    export function bar(): void;
}

import { bar } from "foo";

bar();

Playground link

3 Comments
2024/11/28
08:00 UTC

3

How do I avoid the type assertion at the end of this function?

function createSomething(x: number): Something {
    const something: Partial<Something> = {};

    something.a = complexOperation(x);
    something.b = anotherComplexOperation(something.a);
    // ...
    something.z = someValue;

    return something as Something;
}

The main problem is that the type assertion works even if one of the properties has been left as undefined.

I know if I used a class constructor this would be easier, but this project is avoiding classes because it follows a procedural approach. Apparently TypeScript doesn't support old-school constructor functions, so I'd be glad to find out I'm wrong.

70 Comments
2024/11/27
14:25 UTC

7

How to enforce type to only include values that exist in another object.

I basically have an array of objects like this

const foo = [
    {id: 'abc'},
    {id: '123'},
]

and I want to have an interface who's field must match existing values in the ID field of the foo object e.g.

interface bar {
    foo_ids: *some array of strings type that enforces array of only 'abc' or '123' values*
}

I'm sure there's an elegant solution here?

2 Comments
2024/11/27
13:05 UTC

0

Where to move now?

Hello Everyone,

I've been learning TS for the past couple of days.

So far i learnt

Primitives, arrays,
functions, function parameters, function returns and promises
anonymous functions
object types
narrowing (not the sub categories tho, only equality narrowing)
union types
type aliases
interface
Type Assertions
Literal Types
Stricts

I also did practices with these too.

My question is,

Where to go from here? Should i be using typescript in my projects now or entegrating to non ts projects?

I checked some roadmaps but it did not fit in my head somehow.

Could you recommend me like "You can go through this, would be great", or should i be start using TS with some projects or maybe entegrate it to non TS projects.

Thank you everyone.

17 Comments
2024/11/27
05:25 UTC

1

Pick<> keys from an array

Background story: I'm using supabase js library and I want to retrieve limited number of columns retrieved from the database.

const org = await supabase
.from('orgs')
.select('name, addr, phone')
.eq('ownerId', user?.id)
.limit(1)
.returns<Pick<Tables<'orgs'>, 'name'|'addr'|'phone'>>()

Here, I want to select name, addr and phone columns. The Tables<'orgs'> type is generated by supabase CLI based on the actual database table.

So I thought, instead of repeating the same set of columns once in select function and again in returns generic function, is it possible to create an array of columns and generate the type from that.

const OrgDtoColumns: (keyof Tables<'orgs'>)[] = ['name', 'addr', 'phone']

type OrgDto = CustomPick<Tables<'orgs'>, typeof OrgColumns>

const org = await supabase
.from('orgs')
.select(OrgColumns.join(','))
.eq('ownerId', user?.id)
.limit(1)
.returns<OrgDto>()

First of all, do you think this is a dumb idea? Regardless of this being dumb or not, can I pick the properties from a given type based on an array of keys?

2 Comments
2024/11/27
04:11 UTC

2

Generic or Generic Functions?

Hello Everyone,

I just started to study typescript documentation.

I am in a part of Generic Functions.

The problem is Generic is a whole another topic by itself but the TypeScript document puts it way before Generics itself.

From whichone i should start?

Thank you.

2 Comments
2024/11/27
00:29 UTC

10

Needs a smarter way to do this

I wrote a type to extract keys with singular types(not an object or a collection) in a type.

I can't directly expand the values of the transformed type, so a temp type is required which is ugly, is there better solution to make it cleaner?

const foo = {
  foo: '123',
  bar: 123,
  baz: {
    foo: 1,
  },
  goo: [1, 2, 3],
};

type Foo = typeof foo;
// I have to use a type to store it first
type Temp = {
  [K in keyof Foo]: Foo[K] extends object ? never : Foo[K] extends [] ? never : K;
};
type KeyOfSingularPropertyInFoo = Temp[keyof Temp]; // 'foo' | 'bar'

12 Comments
2024/11/26
16:34 UTC

3

How can this be done correctly ? array of object with generics

ts playground

Copy of the code of the playground


type Misc = {[k:string]: unknown}

type Item<
  TMisc extends Misc
> = {
  name: string,
  misc: TMisc,
  cb: (misc: TMisc) => void
}

const myManager = {
  items: [] as Item<Misc>[],
  addItem: <TMisc extends Misc>(item:Item<TMisc>) => {
    myManager.items.push(item); // ERROR HERE
  },
  // solution that works but use "any"
  // addItem: <TMisc extends Misc>(item:Item<TMisc>) => {
  //   myManager.items.push(item as Item<any>);
  // }
}


myManager.addItem({
  name: 'one',
  misc: {count: 1},
  cb: (misc) => {
    misc
    //^?
  }
})

myManager.addItem({
  name: 'two',
  misc: {age: 45},
  cb: (misc) => {
    misc
    //^?
  }
})

I need that myManager.addItem invokation correctly infer the generic of Item so that cb receives typed misc.

But i get a type error in myManager.items.push(item); // ERROR HERE.

I found a solution (visible in playground) but it requires usage of any, so I'm wondering if there is an alternative... Or instead using any is the right choice here ?

6 Comments
2024/11/26
15:13 UTC

2

Staying DRY while using zod schemas and derivative objects?

I'm a Typescript novice. It feels like there is a way to make my code more DRY, but I don't really know how. For context, I am building a simple form that has both client and server side validation.

I have a zod schema that serves as the contract for both sides:

export const signUpSchema = z.object({
  firstName: z
    .string({ required_error: 'Email is required' })
    .trim()
    .min(8, 'Email must be 8 or more characters')
    .max(64, 'Email must be 64 or less characters')
    .email('Invalid email'),
  lastName: z.string({ required_error: 'Last Name is required' }).trim().min(2),
  email: z
    .string({ required_error: 'Email is required' })
    .trim()
    .min(8, 'Email must be 8 or more characters')
    .max(64, 'Email must be 64 or less characters')
    .email('Invalid email')
});

Since there is a lot of boilerplate with my form when building the UI side, I wanted something like this to represent my form data. This way, I can just build my views off of what I need:

interface Field {
  type: 'text' | 'select';
  label: string;
  name: keyof FormFields;
  placeholder: string;
  required?: boolean;
  mt?: string;
  data?: string[]; // For 'select' fields
}

const firstStepFields: Field[] = [
  {
    type: 'text',
    label: 'First Name',
    name: 'firstName',
    placeholder: 'First Name',
    required: true,
    mt: 'xs',
  },
  {
    type: 'text',
    label: 'Last Name',
    name: 'lastName',
    placeholder: 'Last Name',
    required: true,
    mt: 'xs',
  },
  { type: 'text', label: 'Phone', name: 'phone', placeholder: '123-456-7890', mt: 'xs' },
  {
    type: 'text',
    label: 'Email',
    name: 'email',
    placeholder: 'you@example.dev',
    required: true,
    mt: 'xs',
  },
];

My issue comes in with repeating myself. Multiple times, I have had a mismatch between required in my little field concoction and the zod schema. For example:

city: z.string().trim().min(3).optional(),

At the least, I would like to derive these required values from whether it is required or optional from the zod schema. Is there a way to do this?

Another problem that I encountered: Can this idea extend to the definition of the object itself? I have something like this for the UI form side:

const INITIAL_VALUES = {
  firstName: '',
  lastName: '',
  email: '',
} as const;

type FormFields = typeof INITIAL_VALUES;

Ideally it would be feasible to do something like this:

type SignUpSchema = z.infer<typeof signUpSchema>;

const INITIAL_VALUES = // shape of sign up schema

Thanks in advance for any help.

7 Comments
2024/11/25
22:59 UTC

0

I have a question about Objects and if I'm using them correctly.

First off i am new to typescript but, I'm trying to get with it and trying to learn Objects for a project I am building in react-native-web and react-native. I created a custom interface and am setting that interface to a state variable like this const [clients, setClients] = useState<Client[]>([]); the client interface is setup like this export interface Client  {
  id: number;
  client_name: string;
  client_address: string;
  client_address_2: string;
  client_address_3: string;
  client_address_4: string;
  client_phone: string;
  client_email: string;
  client_services: string;
  client_services_2: string;
  client_services_3: string;
  client_services_4: string;
  notes?: string;

  [key: `client_services_${number}`]: string;

So when I have say a client with multiple addresses and services at multiple addresses im using a Object like this
const [servicesAndAddress, setServicesAndAddress] = useState<{
[key: string]: ServiceWithPrice[];
  }>({});
with another custom interface and using the address as the key. Is this good use of an Object or should i just be assigning 1 variable to the interface and using that to populate the data and also use that same variable to print it back to the jsx component?
This is a long winded question but very confused any help would be much appreciated.

6 Comments
2024/11/25
19:32 UTC

0

Typescript seems to generate a lot of technical debt.. Am i doing it wrong?

29 Comments
2024/11/25
18:04 UTC

32 Comments
2024/11/25
17:59 UTC

Back To Top