Skip to content

Commit

Permalink
fix: enable typescript strictNullChecks
Browse files Browse the repository at this point in the history
  • Loading branch information
LumaKernel authored and kaisermann committed Aug 24, 2021
1 parent 2537314 commit bf4189a
Show file tree
Hide file tree
Showing 16 changed files with 73 additions and 42 deletions.
10 changes: 6 additions & 4 deletions src/cli/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const FORMAT_METHOD_NAMES = new Set(['format', '_', 't']);
function isFormatCall(node: Node, imports: Set<string>) {
if (node.type !== 'CallExpression') return false;

let identifier: Identifier;
let identifier: Identifier | undefined;

if (node.callee.type === 'Identifier') {
identifier = node.callee;
Expand Down Expand Up @@ -125,7 +125,9 @@ export function collectMessageDefinitions(ast: Ast) {
definitionDict.properties.map((propNode) => {
if (propNode.type !== 'Property') {
throw new Error(
`Found invalid '${propNode.type}' at L${propNode.loc.start.line}:${propNode.loc.start.column}`,
`Found invalid '${propNode.type}' at L${propNode.loc!.start.line}:${
propNode.loc!.start.column
}`,
);
}

Expand All @@ -143,7 +145,7 @@ export function collectMessages(markup: string): Message[] {
...definitions.map((definition) => getObjFromExpression(definition)),
...calls.map((call) => {
const [pathNode, options] = call.arguments;
let messageObj;
let messageObj: Partial<Message>;

if (pathNode.type === 'ObjectExpression') {
// _({ ...opts })
Expand All @@ -166,7 +168,7 @@ export function collectMessages(markup: string): Message[] {

return messageObj;
}),
].filter(Boolean);
].filter((Boolean as unknown) as (x: Message | null) => x is Message);
}

export function extractMessages(
Expand Down
6 changes: 4 additions & 2 deletions src/cli/includes/getObjFromExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import type { ObjectExpression, Property, Identifier } from 'estree';

import type { Message } from '../types';

export function getObjFromExpression(exprNode: ObjectExpression) {
return exprNode.properties.reduce<Message>((acc, prop: Property) => {
export function getObjFromExpression(
exprNode: ObjectExpression,
): Partial<Message> {
return exprNode.properties.reduce<Partial<Message>>((acc, prop: Property) => {
// we only want primitives
if (
prop.value.type === 'Literal' &&
Expand Down
4 changes: 2 additions & 2 deletions src/cli/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface Message {
id?: string;
default?: string;
id: string;
default: string;
[key: string]: any;
}
6 changes: 3 additions & 3 deletions src/runtime/configs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ConfigureOptions } from './types';
import type { ConfigureOptions, ConfigureOptionsInit } from './types';
import { $locale } from './stores/locale';

interface Formats {
Expand Down Expand Up @@ -47,13 +47,13 @@ export const defaultOptions: ConfigureOptions = {
ignoreTag: true,
};

const options: ConfigureOptions = defaultOptions;
const options: ConfigureOptions = defaultOptions as any;

export function getOptions() {
return options;
}

export function init(opts: ConfigureOptions) {
export function init(opts: ConfigureOptionsInit) {
const { formats, ...rest } = opts;
const initialLocale = opts.initialLocale || opts.fallbackLocale;

Expand Down
21 changes: 17 additions & 4 deletions src/runtime/includes/formatters.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import IntlMessageFormat from 'intl-messageformat';

import type { MemoizedIntlFormatter } from '../types';
import type {
MemoizedIntlFormatter,
MemoizedIntlFormatterOptional,
} from '../types';
import { getCurrentLocale } from '../stores/locale';
import { getOptions } from '../configs';
import { monadicMemoize } from './memoize';
Expand All @@ -15,6 +18,16 @@ type MemoizedDateTimeFormatterFactory = MemoizedIntlFormatter<
Intl.DateTimeFormatOptions
>;

type MemoizedNumberFormatterFactoryOptional = MemoizedIntlFormatterOptional<
Intl.NumberFormat,
Intl.NumberFormatOptions
>;

type MemoizedDateTimeFormatterFactoryOptional = MemoizedIntlFormatterOptional<
Intl.DateTimeFormat,
Intl.DateTimeFormatOptions
>;

const getIntlFormatterOptions = (
type: 'time' | 'number' | 'date',
name: string,
Expand Down Expand Up @@ -76,17 +89,17 @@ const createTimeFormatter: MemoizedDateTimeFormatterFactory = monadicMemoize(
},
);

export const getNumberFormatter: MemoizedNumberFormatterFactory = ({
export const getNumberFormatter: MemoizedNumberFormatterFactoryOptional = ({
locale = getCurrentLocale(),
...args
} = {}) => createNumberFormatter({ locale, ...args });

export const getDateFormatter: MemoizedDateTimeFormatterFactory = ({
export const getDateFormatter: MemoizedDateTimeFormatterFactoryOptional = ({
locale = getCurrentLocale(),
...args
} = {}) => createDateFormatter({ locale, ...args });

export const getTimeFormatter: MemoizedDateTimeFormatterFactory = ({
export const getTimeFormatter: MemoizedDateTimeFormatterFactoryOptional = ({
locale = getCurrentLocale(),
...args
} = {}) => createTimeFormatter({ locale, ...args });
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/includes/loaderQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function loadLocaleQueue(locale: string, localeQueue: MessagesLoader[]) {

const activeFlushes: { [key: string]: Promise<void> } = {};

export function flush(locale: string): Promise<void> {
export async function flush(locale: string): Promise<void> {
if (!hasLocaleQueue(locale)) {
if (locale in activeFlushes) {
return activeFlushes[locale];
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/includes/lookup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const addToCache = (path: string, locale: string, message: string) => {
return message;
};

export const lookup = (path: string, refLocale: string) => {
export const lookup = (path: string, refLocale: string | null | undefined) => {
if (refLocale == null) return undefined;

if (refLocale in lookupCache && path in lookupCache[refLocale]) {
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function defineMessages(i: Record<string, MessageObject>) {
}

export function waitLocale(locale?: string) {
return flush(locale || getCurrentLocale() || getOptions().initialLocale);
return flush(locale || getCurrentLocale() || getOptions().initialLocale!);
}

export {
Expand Down
4 changes: 3 additions & 1 deletion src/runtime/stores/dictionary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ export function getMessageFromDictionary(locale: string, id: string) {
return match;
}

export function getClosestAvailableLocale(refLocale: string): string | null {
export function getClosestAvailableLocale(
refLocale: string,
): string | null | undefined {
if (refLocale == null) return undefined;

const relatedLocales = getPossibleLocales(refLocale);
Expand Down
9 changes: 3 additions & 6 deletions src/runtime/stores/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { getCurrentLocale, getPossibleLocales, $locale } from './locale';
const formatMessage: MessageFormatter = (id, options = {}) => {
if (typeof id === 'object') {
options = id as MessageObject;
id = options.id;
id = options.id!;
}

const {
Expand Down Expand Up @@ -90,11 +90,8 @@ const formatNumber: NumberFormatter = (n, options) => {
return getNumberFormatter(options).format(n);
};

const getJSON: JSONGetter = <T = any>(
id: string,
locale = getCurrentLocale(),
) => {
return lookup(id, locale) as T;
const getJSON: JSONGetter = (id: string, locale = getCurrentLocale()): any => {
return lookup(id, locale);
};

export const $format = derived([$locale, $dictionary], () => formatMessage);
Expand Down
7 changes: 4 additions & 3 deletions src/runtime/stores/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getClosestAvailableLocale } from './dictionary';
import { $isLoading } from './loading';

let current: string;
const $locale = writable(null);
const $locale = writable<string | null | undefined>(null);

function getSubLocales(refLocale: string) {
return refLocale
Expand Down Expand Up @@ -77,7 +77,8 @@ $locale.set = (newLocale: string): void | Promise<void> => {
};

// istanbul ignore next
$locale.update = (fn: (locale: string) => void | Promise<void>) =>
localeSet(fn(current));
$locale.update = (
fn: (value: string | null | undefined) => string | null | undefined,
) => localeSet(fn(current));

export { $locale };
28 changes: 20 additions & 8 deletions src/runtime/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import type { FormatXMLElementFn, Formats } from 'intl-messageformat';

export interface LocaleDictionary {
[key: string]: LocaleDictionary | string | Array<string | LocaleDictionary>;
[key: string]:
| LocaleDictionary
| string
| Array<string | LocaleDictionary>
| null;
}

export type LocalesDictionary = {
Expand Down Expand Up @@ -49,14 +53,18 @@ export type NumberFormatter = (
options?: IntlFormatterOptions<Intl.NumberFormatOptions>,
) => string;

export type JSONGetter = <T>(id: string, locale?: string) => T;
export type JSONGetter = (id: string, locale?: string) => any;

type IntlFormatterOptions<T> = T & {
format?: string;
locale?: string;
};

export interface MemoizedIntlFormatter<T, U> {
(options: IntlFormatterOptions<U>): T;
}

export interface MemoizedIntlFormatterOptional<T, U> {
(options?: IntlFormatterOptions<U>): T;
}

Expand All @@ -65,10 +73,14 @@ export interface MessagesLoader {
}

export interface ConfigureOptions {
fallbackLocale: string;
formats?: Partial<Formats>;
initialLocale?: string;
loadingDelay?: number;
warnOnMissingMessages?: boolean;
ignoreTag?: boolean;
fallbackLocale: string | null | undefined;
formats: Formats;
initialLocale: string | null;
loadingDelay: number;
warnOnMissingMessages: boolean;
ignoreTag: boolean;
}

export type ConfigureOptionsInit = Pick<ConfigureOptions, 'fallbackLocale'> &
Partial<Record<'formats', Partial<ConfigureOptions['formats']>>> &
Partial<Omit<ConfigureOptions, 'fallbackLocale' | 'formats'>>;
4 changes: 2 additions & 2 deletions test/runtime/includes/loaderQueue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ test('checks if exist queues of locale and its fallbacks', () => {
expect(hasLocaleQueue('en-US')).toBe(true);
});

test("does nothing if there's no queue for a locale", () => {
expect(flush('foo')).toBeUndefined();
test("does nothing if there's no queue for a locale", async () => {
expect(await flush('foo')).toBeUndefined();
});

test('flushes the queue of a locale and its fallbacks and merge the result with the dictionary', async () => {
Expand Down
2 changes: 1 addition & 1 deletion test/runtime/includes/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {

describe('getting client locale', () => {
beforeEach(() => {
delete window.location;
delete (window as any).location;
window.location = {
pathname: '/',
hostname: 'example.com',
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
{
"compilerOptions": {
"allowJs": true,
"strictNullChecks": true,
"noImplicitAny": true,
"sourceMap": false,
"module": "esnext",
"moduleResolution": "node",
"skipLibCheck": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"target": "es2017",
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1263,9 +1263,9 @@
integrity sha512-lg55ArB+ZiHHbBBttLpzD07akz0QPrZgUODNakeC09i62dnrywr9mFErHuaPlB6I7z+sEbK+IYmplahvplCj2g==

"@types/node@^14.14.35":
version "14.14.35"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.35.tgz#42c953a4e2b18ab931f72477e7012172f4ffa313"
integrity sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag==
version "14.17.11"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.11.tgz#82d266d657aec5ff01ca59f2ffaff1bb43f7bf0f"
integrity sha512-n2OQ+0Bz6WEsUjrvcHD1xZ8K+Kgo4cn9/w94s1bJS690QMUWfJPW/m7CCb7gPkA1fcYwL2UpjXP/rq/Eo41m6w==

"@types/normalize-package-data@^2.4.0":
version "2.4.0"
Expand Down

0 comments on commit bf4189a

Please sign in to comment.