
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Lightweight i18n with proper TypeScript support
Turns JSON translation files:
// en.json
{
"thereAreXFeatures": "There is {{count}} feature",
"thereAreXFeatures_plural": "There are {{count}} features",
"nested": {
"works": "Nested works"
},
"andYouCanMissKeys": "And you can miss keys in non-default languages",
"orHaveDifferentPlaceholders": "Or have different placeholders, {{firstName}}"
}
// fr.json
{
"thereAreXFeatures": "Il y a {{count}} fonctionnalité",
"thereAreXFeatures_plural": "Il y a {{count}} fonctionnalités",
"nested": {
"works": "Imbriqué fonctionne"
},
"orHaveDifferentPlaceholders": "Ou avoir des espaces réservés différents, {{username}}"
}
into TypeScript:
// types.ts
export type DeepPartial<T> = { [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]; }
export interface Language {
thereAreXFeatures: (p: { count: number }) => string,
nested: {
works: () => string,
},
andYouCanMissKeys: () => string,
orHaveDifferentPlaceholders: (p: { firstName: string | number, username: string | number }) => string,
}
// en.ts
import { Language } from "./types"
const lang = {
thereAreXFeatures: (p: { count: number }): string => p.count === 1 ? ("There is " + p.count.toString() + " feature") : lang.thereAreXFeatures_plural(p),
thereAreXFeatures_plural: (p: { count: string | number }): string => "There are " + p.count.toString() + " features",
nested: {
works: (): string => "Nested works",
},
andYouCanMissKeys: (): string => "And you can miss keys in non-default languages",
orHaveDifferentPlaceholders: (p: { firstName: string | number }): string => "Or have different placeholders, " + p.firstName.toString() + "",
}
export default lang as Language
// fr.ts
import { Language, DeepPartial } from "./types"
const lang = {
thereAreXFeatures: (p: { count: number }): string => p.count === 1 ? ("Il y a " + p.count.toString() + " fonctionnalité") : lang.thereAreXFeatures_plural(p),
thereAreXFeatures_plural: (p: { count: string | number }): string => "Il y a " + p.count.toString() + " fonctionnalités",
nested: {
works: (): string => "Imbriqué fonctionne",
},
orHaveDifferentPlaceholders: (p: { username: string | number }): string => "Ou avoir des espaces réservés différents, " + p.username.toString() + "",
}
export default lang as DeepPartial<Language>
Install ts-i18n globally, then use it from the CLI
npm i -g ts-i18n
ts-i18n -i i18n/src -o i18n/generated
Where i18n/src is the path to a directory with JSON translation files, and i18n/generated is the path the output directory.
Add ts-i18n as a dev dependency:
npm i -D ts-i18n
Then, in your package.json call it:
{
"scripts": {
"prebuild": "ts-i18n -i i18n/src -o i18n/generated",
}
// ...
}
Where i18n/src is the path to a directory with JSON translation files, and i18n/generated is the path the output directory.
Most i18n libraries are not nice to use in TypeScript. Many don't check even that the translation strings exist, let alone that you are passing the right arguments. The ones that do are often too restrictive in their types between languages, are inefficient for front-end workflows or bundle stuff you don't need.
Having proper TypeScript support improves the developer experience, as your IDE can suggest i18n strings and warns you on non-existing ones. Renaming strings is much easier as you can quickly see all the errors in your codebase. Libraries without TypeScript support make you check you are using the right string, and if you get it wrong you'll just have a runtime error which might be missed.
These libraries have been selected as I think they're good or popular enough to consider. These are only my opinions, and I mean no disrespect to their authors and I'm sure for their intended use cases there was good reason for their design. If I've misrepresented or misunderstood a library I'd be happy to be corrected in a PR :)
Pull requests are welcomed on GitHub! To get started:
npm installnpm run test to run tests with Jestnpm run buildVersions follow the semantic versioning spec.
To release:
npm version <major | minor | patch> to bump the versiongit push --follow-tags to push with tagsFAQs
Lightweight i18n with proper TypeScript support
The npm package ts-i18n receives a total of 21 weekly downloads. As such, ts-i18n popularity was classified as not popular.
We found that ts-i18n demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.