/r/typescript
TypeScript is a language for application-scale JavaScript development.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
Resources
Language
Discussion
/r/typescript
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.
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.
Please give detailed instructions. Thank you in advance.
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.
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"
]
}
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.
Given these ongoing configuration headaches, I'm considering a different approach:
What I'd like to know:
Edit: Using Node.js v18, if that matters.
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..
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?
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)
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?
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.
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.
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.
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.");
}
}
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.
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.
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!
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();
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.
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?
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.
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?
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.
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'
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 ?
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.
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.
Hey, we're currently using TypeScript with GraphQL. One issue that has caught us out on a few occasions is there's no obvious way to catch extra data being sent to the server using TS. I've had a look around and the best solution I've found is here, however it's not foolproof. Does anyone have any pointers on this issue?