Skip to content

Commit

Permalink
feat(@formatjs/intl,react-intl): move IntlFormatter type parameters t…
Browse files Browse the repository at this point in the history
…o methods (#3858)
  • Loading branch information
pyrocat101 committed Oct 11, 2022
1 parent ba2a529 commit 0d03bb6
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 55 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"@lerna-lite/cli": "^1.10.0",
"@lerna-lite/list": "^1.10.0",
"@testing-library/jest-dom": "^5.11.5",
"@testing-library/react": "^12.0.0",
"@testing-library/react": "^13.4.0",
"@types/babel__core": "^7.1.7",
"@types/babel__helper-plugin-utils": "^7.10.0",
"@types/babel__traverse": "^7.1.7",
Expand Down
2 changes: 1 addition & 1 deletion packages/intl-messageformat/src/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,6 @@ Try polyfilling it using "@formatjs/intl-pluralrules"
return mergeLiteral(result)
}

export type FormatXMLElementFn<T, R = string | T | Array<string | T>> = (
export type FormatXMLElementFn<T, R = string | T | (string | T)[]> = (
parts: Array<string | T>
) => R
4 changes: 2 additions & 2 deletions packages/intl/src/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function formatList<T>(
onError: OnErrorFn
},
getListFormat: Formatters['getListFormat'],
values: Parameters<IntlFormatters['formatList']>[0],
values: ReadonlyArray<string | T>,
options: Parameters<IntlFormatters['formatList']>[1] = {}
): Array<T | string> | T | string {
const results = formatListToParts(
Expand Down Expand Up @@ -60,7 +60,7 @@ export function formatListToParts<T>(
onError: OnErrorFn
},
getListFormat: Formatters['getListFormat'],
values: ReadonlyArray<string>,
values: ReadonlyArray<string | T>,
options: Parameters<IntlFormatters['formatList']>[1]
): Part[]
export function formatListToParts<T>(
Expand Down
26 changes: 15 additions & 11 deletions packages/intl/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,11 @@ export type FormatDisplayNameOptions = Omit<
'localeMatcher'
>

export interface IntlFormatters<T = any, R = T> {
/**
* `TBase` is the type constraints of the rich text element in the formatted output.
* For example, with React, `TBase` should be `React.ReactNode`.
*/
export interface IntlFormatters<TBase = unknown> {
formatDateTimeRange(
from: Parameters<DateTimeFormat['formatRange']>[0],
to: Parameters<DateTimeFormat['formatRange']>[1],
Expand Down Expand Up @@ -150,27 +154,27 @@ export interface IntlFormatters<T = any, R = T> {
values?: Record<string, PrimitiveType | FormatXMLElementFn<string, string>>,
opts?: IntlMessageFormatOptions
): string
formatMessage(
formatMessage<T extends TBase>(
descriptor: MessageDescriptor,
values?: Record<string, PrimitiveType | T | FormatXMLElementFn<T, R>>,
values?: Record<string, PrimitiveType | T | FormatXMLElementFn<T>>,
opts?: IntlMessageFormatOptions
): R
): string | T | (T | string)[]
$t(
descriptor: MessageDescriptor,
values?: Record<string, PrimitiveType | FormatXMLElementFn<string, string>>,
opts?: IntlMessageFormatOptions
): string
$t(
$t<T extends TBase>(
descriptor: MessageDescriptor,
values?: Record<string, PrimitiveType | T | FormatXMLElementFn<T, R>>,
values?: Record<string, PrimitiveType | T | FormatXMLElementFn<T>>,
opts?: IntlMessageFormatOptions
): R
): string | T | (T | string)[]
formatList(values: ReadonlyArray<string>, opts?: FormatListOptions): string
formatList(
formatList<T extends TBase>(
values: ReadonlyArray<string | T>,
opts?: FormatListOptions
): T | string | Array<string | T>
formatListToParts(
): T | string | (string | T)[]
formatListToParts<T extends TBase>(
values: ReadonlyArray<string | T>,
opts?: FormatListOptions
): Part[]
Expand Down Expand Up @@ -207,7 +211,7 @@ export interface Formatters {

export interface IntlShape<T = string>
extends ResolvedIntlConfig<T>,
IntlFormatters {
IntlFormatters<T> {
formatters: Formatters
}

Expand Down
1 change: 0 additions & 1 deletion packages/react-intl/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ export const FormattedTime: React.FC<
children?(formattedTime: string): React.ReactElement | null
}
> = createFormattedComponent('formatTime')
// @ts-ignore issue w/ TS Intl types
export const FormattedNumber: React.FC<
NumberFormatOptions &
CustomFormatConfig & {
Expand Down
12 changes: 7 additions & 5 deletions packages/react-intl/tests/unit/components/message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ describe('<FormattedMessage>', () => {
defaultMessage: 'Hello, World!',
}

const H1: React.FC = ({children}) => <h1 data-testid="h1">{children}</h1>
const H1: React.FC<{children: React.ReactNode[]}> = ({children}) => (
<h1 data-testid="h1">{children}</h1>
)
const {getByTestId} = mountWithProvider(
{...descriptor, tagName: H1},
providerProps
Expand Down Expand Up @@ -196,7 +198,7 @@ describe('<FormattedMessage>', () => {
defaultMessage: 'Hello, <b>{name}</b>!',
values: {
name: 'Jest',
b: (name: string) => <b data-testid="b">{name}</b>,
b: name => <b data-testid="b">{name}</b>,
},
},
providerProps
Expand Down Expand Up @@ -252,8 +254,8 @@ describe('<FormattedMessage>', () => {
defaultMessage: 'Hello, <b>{name}<i>!</i></b>',
values: {
name: 'Jest',
b: (chunks: any[]) => <b>{chunks}</b>,
i: (msg: string) => <i>{msg}</i>,
b: chunks => <b>{chunks}</b>,
i: msg => <i>{msg}</i>,
},
},
providerProps
Expand All @@ -269,7 +271,7 @@ describe('<FormattedMessage>', () => {
values: {
name: 'Jest',
b: (chunks: any) => <b>{chunks}</b>,
i: (msg: string) => <i>{msg}</i>,
i: msg => <i>{msg}</i>,
},
},
providerProps
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as ReactIntl from '../../'
import * as React from 'react'
import * as ReactIntl from '../..'
import * as ts from 'typescript'
import fs from 'fs'
import lexer from 'cjs-module-lexer'
Expand Down Expand Up @@ -85,4 +86,29 @@ describe('react-intl', () => {
expect(parsed.exports).toContain(key)
})
})

describe('types', () => {
// https://github.com/formatjs/formatjs/issues/3856
it('works with react18 typing', () => {
function Test() {
const messages = ReactIntl.defineMessages({
greeting: {
id: 'app.greeting',
defaultMessage: 'Hello, <bold>{name}</bold>!',
description: 'Greeting to welcome the user to the app',
},
})

const intl = ReactIntl.useIntl()

return intl.formatMessage(messages.greeting, {
name: 'Eric',
bold: str => <b>{str}</b>,
})
}

// This test only need to pass the type checking.
;<Test />
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('ts-jest transformer', function () {
})
it('Comp', function () {
expect(ReactDOMServer.renderToString(<Component />)).toEqual(
'<span data-reactroot="">lQsqfv<!-- --> - <!-- -->[{&quot;type&quot;:0,&quot;value&quot;:&quot;test message&quot;}]<!-- --> - <!-- --> <!-- -->- <!-- -->fooo</span>'
'<span>lQsqfv<!-- --> - <!-- -->[{&quot;type&quot;:0,&quot;value&quot;:&quot;test message&quot;}]<!-- --> - <!-- --> <!-- -->- <!-- -->fooo</span>'
)
})
})
10 changes: 8 additions & 2 deletions packages/vue-intl/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import {MessageDescriptor} from '@formatjs/intl'
import {
IntlFormatters as CoreIntlFormatters,
MessageDescriptor,
} from '@formatjs/intl'
export * from './plugin'
export * from './provider'
export {intlKey} from './injection-key'
Expand All @@ -10,7 +13,6 @@ export {
MessageDescriptor,
IntlCache,
Formatters,
IntlFormatters,
FormatDisplayNameOptions,
FormatListOptions,
FormatPluralOptions,
Expand All @@ -27,6 +29,10 @@ export {
IntlErrorCode,
IntlError,
} from '@formatjs/intl'
import {VNode} from 'vue'

export type IntlFormatters = CoreIntlFormatters<VNode>

export function defineMessages<
K extends keyof any,
T = MessageDescriptor,
Expand Down
6 changes: 3 additions & 3 deletions packages/vue-intl/provider.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {IntlShape} from '@formatjs/intl'
import {inject, provide} from 'vue'
import {inject, provide, VNode} from 'vue'
import {intlKey} from './injection-key'

export function provideIntl(intl: IntlShape<string>) {
export function provideIntl(intl: IntlShape<VNode>) {
provide(intlKey, intl)
}

export function useIntl() {
const intl = inject<IntlShape<string>>(intlKey)
const intl = inject<IntlShape<VNode>>(intlKey)
if (!intl) {
throw new Error(
`An intl object was not injected. Install the plugin or use provideIntl.`
Expand Down
63 changes: 36 additions & 27 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 0d03bb6

Please sign in to comment.