ban interface usage for component props and state
Summary: another eslint rule for flipper codebase Reviewed By: passy Differential Revision: D33917213 fbshipit-source-id: e60b867d359ef5b94a481edf0eda318ecff17eee
This commit is contained in:
committed by
Facebook GitHub Bot
parent
59b11c5f12
commit
f2abbf63db
@@ -146,6 +146,7 @@ module.exports = {
|
|||||||
'flipper/no-console-error-without-context': [2],
|
'flipper/no-console-error-without-context': [2],
|
||||||
'flipper/no-ts-file-extension': 2,
|
'flipper/no-ts-file-extension': 2,
|
||||||
'flipper/no-i-prefix-interfaces': 2,
|
'flipper/no-i-prefix-interfaces': 2,
|
||||||
|
'flipper/no-interface-props-or-state': 2,
|
||||||
'communist-spelling/communist-spelling': [1, {allow: ['cancelled']}],
|
'communist-spelling/communist-spelling': [1, {allow: ['cancelled']}],
|
||||||
|
|
||||||
// promise rules, see https://github.com/xjamundx/eslint-plugin-promise for details on each of them
|
// promise rules, see https://github.com/xjamundx/eslint-plugin-promise for details on each of them
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ import noTsFileExtension, {
|
|||||||
import noIPrefixInterfaces, {
|
import noIPrefixInterfaces, {
|
||||||
RULE_NAME as noIPrefixInterfacesRuleName,
|
RULE_NAME as noIPrefixInterfacesRuleName,
|
||||||
} from './rules/noIPrefixInterfaces';
|
} from './rules/noIPrefixInterfaces';
|
||||||
|
import noInterfaceProps, {
|
||||||
|
RULE_NAME as noInterfacePropsRuleName,
|
||||||
|
} from './rules/noInterfacePropsOrState';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
rules: {
|
rules: {
|
||||||
@@ -30,5 +33,6 @@ module.exports = {
|
|||||||
[noConsoleErrorWithoutContextRuleName]: noConsoleErrorWithoutContext,
|
[noConsoleErrorWithoutContextRuleName]: noConsoleErrorWithoutContext,
|
||||||
[noTsFileExtensionRuleName]: noTsFileExtension,
|
[noTsFileExtensionRuleName]: noTsFileExtension,
|
||||||
[noIPrefixInterfacesRuleName]: noIPrefixInterfaces,
|
[noIPrefixInterfacesRuleName]: noIPrefixInterfaces,
|
||||||
|
[noInterfacePropsRuleName]: noInterfaceProps,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {createESLintRule} from '../utils/createEslintRule';
|
||||||
|
|
||||||
|
type Options = [];
|
||||||
|
|
||||||
|
export type MessageIds = 'noInterfacePropsOrState';
|
||||||
|
export const RULE_NAME = 'no-interface-props-or-state';
|
||||||
|
|
||||||
|
export default createESLintRule<Options, MessageIds>({
|
||||||
|
name: RULE_NAME,
|
||||||
|
meta: {
|
||||||
|
type: 'problem',
|
||||||
|
docs: {
|
||||||
|
description: 'Use type aliases for component props instead of interfaces',
|
||||||
|
recommended: 'error',
|
||||||
|
},
|
||||||
|
schema: [],
|
||||||
|
messages: {
|
||||||
|
noInterfacePropsOrState:
|
||||||
|
'Use type aliases for component props and state instead of interfaces',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultOptions: [],
|
||||||
|
create(context) {
|
||||||
|
return {
|
||||||
|
TSInterfaceDeclaration(node) {
|
||||||
|
if (
|
||||||
|
!(node.id.name.endsWith('Props') || node.id.name.endsWith('State'))
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.report({
|
||||||
|
node: node.id,
|
||||||
|
messageId: 'noInterfacePropsOrState',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -213,12 +213,12 @@ export const DataList: (<T extends object>(
|
|||||||
enableArrow: true,
|
enableArrow: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
interface DataListItemProps {
|
type DataListItemProps = {
|
||||||
// TODO: add icon support
|
// TODO: add icon support
|
||||||
title?: string | React.ReactElement;
|
title?: string | React.ReactElement;
|
||||||
description?: string | React.ReactElement;
|
description?: string | React.ReactElement;
|
||||||
enableArrow?: boolean;
|
enableArrow?: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
const ArrowWrapper = styled.div({
|
const ArrowWrapper = styled.div({
|
||||||
flex: 0,
|
flex: 0,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ import {debounce} from 'lodash';
|
|||||||
import {useInUnitTest} from '../../utils/useInUnitTest';
|
import {useInUnitTest} from '../../utils/useInUnitTest';
|
||||||
import {createDataSource} from '../../state/createDataSource';
|
import {createDataSource} from '../../state/createDataSource';
|
||||||
|
|
||||||
interface DataTableBaseProps<T = any> {
|
type DataTableBaseProps<T = any> = {
|
||||||
columns: DataTableColumn<T>[];
|
columns: DataTableColumn<T>[];
|
||||||
enableSearchbar?: boolean;
|
enableSearchbar?: boolean;
|
||||||
enableAutoScroll?: boolean;
|
enableAutoScroll?: boolean;
|
||||||
@@ -73,7 +73,7 @@ interface DataTableBaseProps<T = any> {
|
|||||||
onRenderEmpty?:
|
onRenderEmpty?:
|
||||||
| null
|
| null
|
||||||
| ((dataSource?: DataSource<T, T[keyof T]>) => React.ReactElement);
|
| ((dataSource?: DataSource<T, T[keyof T]>) => React.ReactElement);
|
||||||
}
|
};
|
||||||
|
|
||||||
export type ItemRenderer<T> = (
|
export type ItemRenderer<T> = (
|
||||||
item: T,
|
item: T,
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ import {updateSettings} from '../reducers/settings';
|
|||||||
import {switchPlugin} from '../reducers/pluginManager';
|
import {switchPlugin} from '../reducers/pluginManager';
|
||||||
import {awaitPluginCommandQueueEmpty} from '../dispatcher/pluginManager';
|
import {awaitPluginCommandQueueEmpty} from '../dispatcher/pluginManager';
|
||||||
|
|
||||||
interface PersistedState {
|
type PersistedState = {
|
||||||
count: 1;
|
count: 1;
|
||||||
}
|
};
|
||||||
|
|
||||||
class TestPlugin extends FlipperPlugin<any, any, any> {
|
class TestPlugin extends FlipperPlugin<any, any, any> {
|
||||||
static id = 'TestPlugin';
|
static id = 'TestPlugin';
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ import {FlipperPlugin} from '../plugin';
|
|||||||
import {TestIdler} from '../utils/Idler';
|
import {TestIdler} from '../utils/Idler';
|
||||||
import {getAllClients} from '../reducers/connections';
|
import {getAllClients} from '../reducers/connections';
|
||||||
|
|
||||||
interface PersistedState {
|
type PersistedState = {
|
||||||
count: 1;
|
count: 1;
|
||||||
}
|
};
|
||||||
|
|
||||||
class TestPlugin extends FlipperPlugin<any, any, any> {
|
class TestPlugin extends FlipperPlugin<any, any, any> {
|
||||||
static id = 'TestPlugin';
|
static id = 'TestPlugin';
|
||||||
|
|||||||
@@ -158,7 +158,6 @@ To start Flipper against a specific OnDemand instance, set FB_ONDEMAND flag, e.g
|
|||||||
</FbInternalOnly>
|
</FbInternalOnly>
|
||||||
|
|
||||||
## Guidelines for writing TypeScript
|
## Guidelines for writing TypeScript
|
||||||
* Prefer `type` for React props and state over interfaces
|
|
||||||
* Install 3rd party type definitions as dev dependency (e.g. `yarn add @types/lodash --dev`)
|
* Install 3rd party type definitions as dev dependency (e.g. `yarn add @types/lodash --dev`)
|
||||||
|
|
||||||
## Submitting a diff / PR
|
## Submitting a diff / PR
|
||||||
|
|||||||
Reference in New Issue
Block a user