-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathindex.tsx
58 lines (52 loc) · 1.45 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// @ts-expect-error
import React from "react";
// @ts-expect-error
import { FormattedMessage } from "react-intl";
const messages = {
en: {
GREETING: "Hello {name}",
INTRO: "My name is {name} & I'm {age} years old",
HEADER: "Typesafe react-int is {expression}, TS is {love}",
},
fr: {
GREETING: "Hello {name}",
INTRO: "My name is {name} & I'm {age} years old",
HEADER: "Typesafe react-int is {expression}, TS is {love}",
},
} as const;
export type Messages = typeof messages["en"];
export type ExtractValues<T extends string> =
T extends `${string}{${infer Prop}}${infer Rest}`
? Prop | ExtractValues<Rest>
: never;
type Props = Omit<
React.ComponentProps<typeof FormattedMessage>,
"id" | "values"
>;
const TypedFormattedMessage = <Id extends keyof Messages>(
props: Props & {
id: Id;
values: Record<ExtractValues<Messages[Id]>, React.ReactNode>;
}
) => {
return <FormattedMessage {...props} />;
};
const t = (
<>
<TypedFormattedMessage id="GREETING" values={{ name: "Anurag" }} />
<TypedFormattedMessage
id="HEADER"
values={{ expression: "Amazing", love: "love" }}
// ^ proper intellisense
/>
<TypedFormattedMessage
id="INTRO"
// @ts-expect-error age is missing
values={{ name: "Anurag" }}
/>
<TypedFormattedMessage
// @ts-expect-error Type '"INVALID-ID"' is not assignable to type '"GREETING" | "MSG" | "HEADER"'
id="INVALID-ID"
/>
</>
);