New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[explicit-module-boundary-types] add option to allow arguments explicitly typed as any
#2119
Comments
Could you please include a link to your example code? |
I updated typescriptlang.org playground link in my original comment which should have the code, but if not here it is. type LogCallback = (error?: any, level?: string, message?: string, meta?: any) => void
interface LeveledLogMethod {
(message: string, callback: LogCallback): Logger
(message: string, meta: any, callback: LogCallback): Logger
(message: string, ...meta: any[]): Logger
(infoObject: object): Logger
}
export interface Logger {
critical: LeveledLogMethod;
error: LeveledLogMethod;
info: LeveledLogMethod;
debug: LeveledLogMethod;
}
export declare type ApolloLogger = {
debug(message?: any): void
info(message?: any): void
warn(message?: any): void
error(message?: any): void
}
export function apolloLoggerAdapter(logger: Logger): ApolloLogger {
return {
debug (message: string) {
return logger.debug(message)
},
info (message: string) {
return logger.info(message)
},
warn (message: string) {
return logger.info(`warning: ${message}`)
},
error (message: string) {
return logger.error(message)
}
}
} |
The issue is the I could probably be made clearer, but there is one example in the docs: // All arguments should be typed
export var arrowFn = (arg): string => `test ${arg}`;
export var arrowFn = (arg: any): string => `test ${arg}`; You can switch from Also looking at your example code - it's super unsafe. Your interface defines the properties as This is a massive safety hole and means your code is liable to break if someone does something like pass a number or an object in. |
@bradzacher
Fair point on the unsafe interfaces there, I actually have a similar example though where this still happens without the export declare type CacheValue<T> = T | (() => T) | (() => Promise<T>);
export interface CacheOptions {
group?: string;
}
export interface ExpireCacheOptions extends CacheOptions {
duration?: number | null;
}
export interface Cache {
get<T>(key: string, options?: CacheOptions): Promise<T | undefined>;
set<T>(key: string, value: CacheValue<T>, options?: ExpireCacheOptions): Promise<T>;
delete(key: string | string[], options?: CacheOptions): Promise<boolean>;
deleteGroup(group: string | string[]): Promise<boolean>;
remember<T>(key: string, value: CacheValue<T>, options?: ExpireCacheOptions): Promise<T>;
clear(): Promise<boolean>;
}
export interface KeyValueCacheSetOptions {
ttl?: number | null
};
export interface KeyValueCache<V = string> {
get(key: string): Promise<V | undefined>;
set(key: string, value: V, options?: KeyValueCacheSetOptions): Promise<void>;
delete(key: string): Promise<boolean | void>;
}
export function apolloKeyValueCacheAdapter(cache: Cache): KeyValueCache {
return {
get (key) {
return cache.get(key)
},
set (key, value, options = {}) {
return cache.set(key, value, { duration: options.ttl || 3600 })
.then(() => undefined)
},
delete (key) {
return cache.delete(key)
}
}
} One way to get the error to stop in this case and the last example I gave is to create a local variable like export function apolloKeyValueCacheAdapter (cache: Cache): KeyValueCache {
const keyValueCache: KeyValueCache = {
get (key) {
return cache.get(key)
},
set (key, value, options = {}) {
return cache.set(key, value, { duration: options.ttl || 3600 })
.then(() => undefined)
},
delete (key) {
return cache.delete(key)
}
}
return keyValueCache
} Obviously this local variable is redundant and should not be needed but it removes the warnings I get from explicit-module-boundary-types which does not make sense to me. Sorry for the walls of code, I'm just copying the interfaces from node_modules until I have them all accounted for to make the example function work. |
The intention of the rule is that you provide clear and explicit module boundaries. Explicitly typing This is working as expected. If you'd like to contribute a clarification to the docs, I'm happy to accept a PR. As for this rule and alternatives:
|
any
I have added an option - @AlCalzone - the PR I mentioned didn't fix that issue, so I raised #2134, and fixed it as well. |
Thanks for the update. I feel like this eslint rule though would be better served not caring about |
It is possible that this is expected behavior, but the docs are very unclear to me. Most of the examples have functions that simply return primitives or higher order functions, but nothing about returning interfaces/types from functions.
Repro
Here is a typescript playground with the minimum reproduction of the issue. Essentially the
apolloLoggerAdapter
is trying to adapt oneLogger
interface into anotherApolloLogger
interface. The function is returning anApolloLogger
interface which is pretty explicit about the expected object. I shouldn't have to retype the methodsdebug
,info
,warn
, anderror
.https://www.typescriptlang.org/play/?ssl=1&ssc=1&pln=40&pc=1#code/C4TwDgpgBAMg9gcwMIEMA2aBGKDGBrKAXigAoIAncucgfgC4oUA7EAGijQgDcI16oAzsHIBLJgnYBbCAIEoEEfkNHipEYCn7MQASiIA+KFzgiAJgChzY4BQBmuaDG68Ip+AgCy6gBZxTUAG9zKBDSaVl5CAZlMQkoHHQsXDwGd1QMbHwdVMQFcmDQknC5BWjhWLUNBm12BIzknOREzLxs2FyKApCimRKowXLVKAA6UekqxhYAbQBdNvc8rtIxWzgAeUwAKwgcYAY4LZ3geY78kIBfSwgADzBqYChrOwd2hDzApZxRYBE61OdOG5EF5gL5TABuJYUKjkf48QHuEFgyGhR5MVZwlxAzw+Pwo0KmCCYACuCExCOBuIh5ku5hud3ID0JODQKHI0FAkCgAEE7hg4AsKEQPiFCSSED0IgotCw2sYzAUVnBJX0ZboGPKLCEAO5spgqyJquUmLVQaHUA3S6qyjUmmlXW73KC2YlMXYiOBMRh8tAC07c0woMA2cgkX1vCiNPJtXlwfmC8giqDs4DE8heoKosWksK9SJlFQIPSZ1HJ9Rpr3hvLDbMS4qRHRLc6sJZK3NS-oxcTFpYhFMVjinYZKy0QRuo5tLXXp9t9AuxHulsupmdVijD9HKgAG06YsQYABIAvWFOct+PQpPUebE6P592k6j+6uhzfRxeLgVLpcgA
I'm using whatever the
plugin:@typescript-eslint/recommended
settings are.Expected Result
I should not get warnings about "Missing return type on function" or "Argument 'message' should be typed".
Actual Result
I do get warnings even though the function explicitly returns an object with already typed methods.
Additional Info
Versions
@typescript-eslint/eslint-plugin
3.0.1
@typescript-eslint/parser
3.0.1
TypeScript
3.9.3
ESLint
7.1.0
node
12.16.1
npm
6.14.5
The text was updated successfully, but these errors were encountered: