Skip to content

Commit

Permalink
fix: @lingui/macro types for global environments (#973)
Browse files Browse the repository at this point in the history
  • Loading branch information
semoal committed Feb 8, 2021
1 parent 5656c95 commit 92a5ce7
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 10 deletions.
25 changes: 24 additions & 1 deletion docs/guides/typescript.rst
Expand Up @@ -2,7 +2,7 @@
Typescript
**********

Lingui supports typescript out of the box since version ``3.0.0``. Feel free to submit any query you find related to typescript on Github Issues
Lingui supports typescript types out of the box since version ``3.0.0``. Feel free to submit any query you find related to typescript on Github Issues

Webpack setup
=============
Expand Down Expand Up @@ -62,6 +62,29 @@ otherwise compiled catalogs can't be imported using ES ``import``, but rather Co
"compileNamespace": "ts"
}
Macros types in non-React environments
======================================

Since the opening of this issue we investigated that macros can be used on Typescript environments where React isn't required.

Now we're shipping two declaration types:
- ``index.d.ts`` files with ``@lingui/core``, ``@lingui/react`` and ``react`` as peerDependencies.
- ``global.d.ts`` files with just ``@lingui/core`` as peerDependencies.

Now you can modify your ``tsconfig.json`` in your root directory and reference the global file:

.. code-block:: json
{
"compilerOptions": {
"types": [
"./node_modules/@lingui/macro/global",
]
}
}
Type definitions
================

Expand Down
63 changes: 63 additions & 0 deletions packages/macro/global.d.ts
@@ -0,0 +1,63 @@
declare module '@lingui/macro' {
import type { MessageDescriptor } from "@lingui/core"

export type BasicType = {
id?: string
comment?: string
}

export function t(
literals: TemplateStringsArray | MessageDescriptor,
...placeholders: any[]
): string

export type UnderscoreDigit<T = string> = { [digit: string]: T }
export type ChoiceOptions<T = string> = {
offset?: number
zero?: T
one?: T
few?: T
many?: T
other?: T
} & UnderscoreDigit<T>

export function plural(arg: number | string, options: ChoiceOptions & BasicType): string
export function selectOrdinal(
arg: number | string,
options: ChoiceOptions & BasicType
): string
export function select(arg: string, choices: Record<string, string> & BasicType): string
export function defineMessages<M extends Record<string, MessageDescriptor>>(
messages: M
): M
export function defineMessage(descriptor: MessageDescriptor): MessageDescriptor

export type ChoiceProps = {
value?: string | number
} & ChoiceOptions<string>

/**
* The types should be changed after this PR is merged
* https://github.com/Microsoft/TypeScript/pull/26797
*
* then we should be able to specify that key of values is same type as value.
* We would be able to remove separate type Values = {...} definition
* eg.
* type SelectProps<Values> = {
* value?: Values
* [key: Values]: string
* }
*
*/
type Values = { [key: string]: string }

export type SelectProps = {
value: string
other: any
} & Values

export const Trans: any
export const Plural: any
export const Select: any
export const SelectOrdinal: any
}
1 change: 1 addition & 0 deletions packages/macro/package.json
Expand Up @@ -25,6 +25,7 @@
"LICENSE",
"README.md",
"*.js",
"global.d.ts",
"index.d.ts"
],
"dependencies": {
Expand Down
21 changes: 12 additions & 9 deletions scripts/build/babel.js
Expand Up @@ -30,6 +30,10 @@ function walk(base, relativePath = "") {
return files
}

function declarationFinder(typesPath) {
return typesPath.map(p => fs.existsSync(p) && path.basename(p)).filter(Boolean)
}

module.exports = async function(bundle) {
const logKey = chalk.white.bold(bundle.entry)

Expand All @@ -39,14 +43,13 @@ module.exports = async function(bundle) {
const resolvedEntry = require.resolve(bundle.entry)
const packageDir = path.dirname(resolvedEntry)
const srcDir = path.join(packageDir, "src")

const declarationFilePath = path.join(packageDir, "index.d.ts")

const files = walk(srcDir)

if (fs.existsSync(declarationFilePath)) {
files.push("index.d.ts")
}
const files = [
...walk(srcDir),
...declarationFinder([
path.join(packageDir, "index.d.ts"),
path.join(packageDir, "global.d.ts"),
])
]

for (const filename of files) {
const [mainOutputPath] = Packaging.getBundleOutputPaths(
Expand All @@ -65,7 +68,7 @@ module.exports = async function(bundle) {
)
fs.writeFileSync(mainOutputPath.replace(/\.ts$/, ".js"), code)
} else {
fs.copyFileSync(path.join(packageDir, filename), mainOutputPath)
fs.copyFileSync(path.join(packageDir, filename), path.join(outputDir, filename))
}
}
} catch (error) {
Expand Down

1 comment on commit 92a5ce7

@vercel
Copy link

@vercel vercel bot commented on 92a5ce7 Feb 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.