0
0
mirror of https://github.com/PostHog/posthog.git synced 2024-11-21 21:49:51 +01:00

chore(frontend): Fix all typescript errors (#10092)

* fix dayjs

* fix timeouts (we're not strictly speaking running in nodejs)

* export unexported type

* consolidate on a single FormInstance

* no need to rename

* fuse

* forminstance 2

* locationChanged

* BuiltLogic

* remove Type.ts exception

* fix duh

* lay off the bin/check-typescript/strict script

* don't think this is ever used or useful

* no real need to hide the output

* make typescript:check do what the name says

* we're already strict

Co-authored-by: Michael Matloka <dev@twixes.com>
This commit is contained in:
Marius Andra 2022-06-03 12:17:49 +02:00 committed by GitHub
parent 9faad16402
commit 15017ca714
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 71 additions and 62 deletions

View File

@ -34,9 +34,8 @@ jobs:
- name: Lint with ESLint
run: yarn eslint
- name: Run typescript with strict
run: |
./bin/check-typescript-strict
- name: Generate logic types and run typescript with strict
run: yarn typegen:write && yarn typescript:check
jest-setup:
# Split the tests into multiple chunks

View File

@ -128,4 +128,4 @@ jobs:
# Below DB name has `test_` prepended, as that's how Django (ran above) creates the test DB
DATABASE_URL: 'postgres://postgres:postgres@localhost:5432/test_posthog'
REDIS_URL: 'redis://localhost'
run: cd plugin-server && yarn typescript:check && yarn test:${{matrix.group}}
run: cd plugin-server && yarn test:${{matrix.group}}

View File

@ -1,23 +0,0 @@
#!/bin/bash
echo "Refreshing Kea logic types and running the TypeScript compiler in dry mode..."
echo
IGNORED_SPECS=('Type.ts') # *Type.ts* files are ignored, as they are generally created by kea-typegen
yarn typegen:write &> /dev/null
ALL_ERRORS=$(yarn typescript:check --strict 2> /dev/null | grep error | grep frontend)
ERRORS_COUNT=$(echo "${ALL_ERRORS}" | wc -l)
NEW_ERRORS=$(echo "${ALL_ERRORS}" | grep --invert-match --fixed-strings ${IGNORED_SPECS})
NEW_ERRORS_COUNT="$(echo "${NEW_ERRORS}" | wc -l)"
if test -z "${NEW_ERRORS}"
then
echo "No TypeScript errors found in this PR! 🚀"
exit 0
else
echo "Found ${NEW_ERRORS_COUNT} TypeScript errors in this PR! 💥"
echo "${NEW_ERRORS}"
exit 1
fi

View File

@ -1,6 +1,6 @@
import { kea } from 'kea'
import api from 'lib/api'
import { dayjs, now } from 'lib/dayjs'
import { dayjs, now, OpUnitType } from 'lib/dayjs'
import { deleteWithUndo, determineDifferenceType, groupBy, toParams } from '~/lib/utils'
import { annotationsModel } from '~/models/annotationsModel'
import { getNextKey } from './utils'
@ -29,7 +29,7 @@ export const annotationsLogic = kea<annotationsLogicType>({
}),
deleteAnnotation: (id: string) => ({ id }),
updateDiffType: (dates: string[]) => ({ dates }),
setDiffType: (type: dayjs.OpUnitType) => ({ type }),
setDiffType: (type: OpUnitType) => ({ type }),
}),
loaders: ({ props }) => ({
annotations: {
@ -90,7 +90,7 @@ export const annotationsLogic = kea<annotationsLogicType>({
(annotationsList, diffType) =>
groupBy(annotationsList, (annotation) =>
dayjs(annotation['date_marker'])
.startOf(diffType as dayjs.OpUnitType)
.startOf(diffType as OpUnitType)
.format('YYYY-MM-DD')
),
],

View File

@ -5,7 +5,7 @@ import { eventUsageLogic } from 'lib/utils/eventUsageLogic'
import type { saveToDashboardModalLogicType } from './saveToDashboardModalLogicType'
import { newDashboardLogic } from 'scenes/dashboard/newDashboardLogic'
import { DashboardType, InsightModel, InsightType } from '~/types'
import Fuse from 'fuse.js'
import FuseClass from 'fuse.js'
import { lemonToast } from 'lib/components/lemonToast'
import { router } from 'kea-router'
import { urls } from 'scenes/urls'
@ -15,6 +15,11 @@ export interface SaveToDashboardModalLogicProps {
insight: Partial<InsightModel>
fromDashboard?: number
}
// Helping kea-typegen navigate the exported default class for Fuse
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface Fuse extends FuseClass<any> {}
export const saveToDashboardModalLogic = kea<saveToDashboardModalLogicType>({
path: ['lib', 'components', 'SaveToDashboard', 'saveToDashboardModalLogic'],
props: {} as SaveToDashboardModalLogicProps,
@ -71,8 +76,8 @@ export const saveToDashboardModalLogic = kea<saveToDashboardModalLogicType>({
],
dashboardsFuse: [
() => [dashboardsModel.selectors.nameSortedDashboards],
(nameSortedDashboards) => {
return new Fuse(nameSortedDashboards || [], {
(nameSortedDashboards): Fuse => {
return new FuseClass(nameSortedDashboards || [], {
keys: ['name', 'description', 'tags'],
threshold: 0.3,
})
@ -82,7 +87,7 @@ export const saveToDashboardModalLogic = kea<saveToDashboardModalLogicType>({
(s) => [s.searchQuery, s.dashboardsFuse, dashboardsModel.selectors.nameSortedDashboards],
(searchQuery, dashboardsFuse, nameSortedDashboards): DashboardType[] =>
searchQuery.length
? dashboardsFuse.search(searchQuery).map((r: Fuse.FuseResult<DashboardType>) => r.item)
? dashboardsFuse.search(searchQuery).map((r: FuseClass.FuseResult<DashboardType>) => r.item)
: nameSortedDashboards,
],
currentDashboards: [

View File

@ -1,5 +1,5 @@
// eslint-disable-next-line no-restricted-imports
import dayjs, { Dayjs } from 'dayjs'
import dayjs, { Dayjs as DayjsOriginal } from 'dayjs'
import LocalizedFormat from 'dayjs/plugin/localizedFormat'
import relativeTime from 'dayjs/plugin/relativeTime'
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'
@ -20,3 +20,30 @@ dayjs.extend(duration)
const now = (): Dayjs => dayjs()
export { dayjs, now }
// The lines below are copied from "node_modules/dayjs/index.ts" to help typescript and typegen.
// We could only use types like "dayjs.OpUnitType", causing errors such as:
// error TS2312: An interface can only extend an object type or intersection of object types with statically known members.
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface Dayjs extends DayjsOriginal {}
export type UnitTypeShort = 'd' | 'M' | 'y' | 'h' | 'm' | 's' | 'ms'
export type UnitTypeLong = 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'month' | 'year' | 'date'
export type UnitTypeLongPlural =
| 'milliseconds'
| 'seconds'
| 'minutes'
| 'hours'
| 'days'
| 'months'
| 'years'
| 'dates'
export type UnitType = UnitTypeLong | UnitTypeLongPlural | UnitTypeShort
export type OpUnitType = UnitType | 'week' | 'weeks' | 'w'
export type QUnitType = UnitType | 'quarter' | 'quarters' | 'Q'
export type ManipulateType = Omit<OpUnitType, 'date' | 'dates'>

View File

@ -24,7 +24,7 @@ import {
FilterLogicalOperator,
PropertyFilterValue,
} from '~/types'
import { dayjs } from 'lib/dayjs'
import type { Dayjs } from 'lib/dayjs'
import { preflightLogic } from 'scenes/PreflightCheck/preflightLogic'
import type { PersonsModalParams } from 'scenes/trends/personsModalLogic'
import { EventIndex } from '@posthog/react-rrweb-player'
@ -267,9 +267,9 @@ export const eventUsageLogic = kea<eventUsageLogicType>({
delay,
}),
reportDashboardModeToggled: (mode: DashboardMode, source: DashboardEventSource | null) => ({ mode, source }),
reportDashboardRefreshed: (lastRefreshed?: string | dayjs.Dayjs | null) => ({ lastRefreshed }),
reportDashboardRefreshed: (lastRefreshed?: string | Dayjs | null) => ({ lastRefreshed }),
reportDashboardItemRefreshed: (dashboardItem: InsightModel) => ({ dashboardItem }),
reportDashboardDateRangeChanged: (dateFrom?: string | dayjs.Dayjs, dateTo?: string | dayjs.Dayjs | null) => ({
reportDashboardDateRangeChanged: (dateFrom?: string | Dayjs, dateTo?: string | Dayjs | null) => ({
dateFrom,
dateTo,
}),
@ -369,10 +369,10 @@ export const eventUsageLogic = kea<eventUsageLogicType>({
reportExperimentArchived: (experiment: Experiment) => ({ experiment }),
reportExperimentCreated: (experiment: Experiment) => ({ experiment }),
reportExperimentViewed: (experiment: Experiment) => ({ experiment }),
reportExperimentLaunched: (experiment: Experiment, launchDate: dayjs.Dayjs) => ({ experiment, launchDate }),
reportExperimentLaunched: (experiment: Experiment, launchDate: Dayjs) => ({ experiment, launchDate }),
reportExperimentCompleted: (
experiment: Experiment,
endDate: dayjs.Dayjs,
endDate: Dayjs,
duration: number,
significant: boolean
) => ({

View File

@ -42,7 +42,7 @@ export const cohortEditLogic = kea<cohortEditLogicType>([
deleteCohort: true,
fetchCohort: (id: CohortType['id']) => ({ id }),
onCriteriaChange: (newGroup: Partial<CohortGroupType>, id: string) => ({ newGroup, id }),
setPollTimeout: (pollTimeout: NodeJS.Timeout | null) => ({ pollTimeout }),
setPollTimeout: (pollTimeout: number | null) => ({ pollTimeout }),
checkIfFinishedCalculating: (cohort: CohortType) => ({ cohort }),
setOuterGroupsType: (type: FilterLogicalOperator) => ({ type }),
@ -138,7 +138,7 @@ export const cohortEditLogic = kea<cohortEditLogicType>([
},
],
pollTimeout: [
null as NodeJS.Timeout | null,
null as number | null,
{
setPollTimeout: (_, { pollTimeout }) => pollTimeout,
},
@ -262,7 +262,7 @@ export const cohortEditLogic = kea<cohortEditLogicType>([
checkIfFinishedCalculating: async ({ cohort }, breakpoint) => {
if (cohort.is_calculating) {
actions.setPollTimeout(
setTimeout(async () => {
window.setTimeout(async () => {
const newCohort = await api.cohorts.get(cohort.id)
breakpoint()
actions.checkIfFinishedCalculating(newCohort)

View File

@ -7,7 +7,7 @@ import type { confirmOrganizationLogicType } from './confirmOrganizationLogicTyp
import { forms } from 'kea-forms'
import { lemonToast } from 'lib/components/lemonToast'
interface ConfirmOrganizationFormValues {
export interface ConfirmOrganizationFormValues {
organization_name?: string
first_name?: string
}

View File

@ -31,6 +31,7 @@ export const inviteLogic = kea<inviteLogicType>({
},
connect: {
values: [preflightLogic, ['preflight']],
actions: [router, ['locationChanged']],
},
reducers: () => ({
isInviteModalShown: [
@ -38,7 +39,7 @@ export const inviteLogic = kea<inviteLogicType>({
{
showInviteModal: () => true,
hideInviteModal: () => false,
[router.actionTypes.locationChanged]: () => false,
locationChanged: () => false,
},
],
invitesToSend: [

View File

@ -1,7 +1,7 @@
import { FormInstance } from 'antd'
import type { FormInstance } from 'antd/lib/form/hooks/useForm.d'
import { kea } from 'kea'
import api from 'lib/api'
import { interfaceJobsLogicType } from './interfaceJobsLogicType'
import type { interfaceJobsLogicType } from './interfaceJobsLogicType'
import { pluginsLogic } from 'scenes/plugins/pluginsLogic'
import { JobSpec } from '~/types'
import { lemonToast } from 'lib/components/lemonToast'
@ -25,7 +25,7 @@ export const interfaceJobsLogic = kea<interfaceJobsLogicType>({
setRunJobAvailable: (isAvailable: boolean) => ({ isAvailable }),
runJob: (form: FormInstance<any>) => ({ form }),
playButtonOnClick: (form: FormInstance<any>, jobHasEmptyPayload: boolean) => ({ form, jobHasEmptyPayload }),
setRunJobAvailableTimeout: (timeout: NodeJS.Timeout) => ({ timeout }),
setRunJobAvailableTimeout: (timeout: number) => ({ timeout }),
},
reducers: {
isJobModalOpen: [
@ -41,7 +41,7 @@ export const interfaceJobsLogic = kea<interfaceJobsLogicType>({
},
],
runJobAvailableTimeout: [
null as NodeJS.Timeout | null,
null as number | null,
{
setRunJobAvailableTimeout: (_, { timeout }) => timeout,
},
@ -87,10 +87,10 @@ export const interfaceJobsLogic = kea<interfaceJobsLogicType>({
if (values.runJobAvailableTimeout) {
clearTimeout(values.runJobAvailableTimeout)
}
setTimeout(() => {
const timeout = actions.setRunJobAvailable(true)
actions.setRunJobAvailableTimeout(timeout)
const timeout = window.setTimeout(() => {
actions.setRunJobAvailable(true)
}, 15000)
actions.setRunJobAvailableTimeout(timeout)
lemonToast.success('Job has been enqueued')
},

View File

@ -14,7 +14,7 @@ import {
import { userLogic } from 'scenes/userLogic'
import { getConfigSchemaArray, getConfigSchemaObject, getPluginConfigFormData } from 'scenes/plugins/utils'
import posthog from 'posthog-js'
import { FormInstance } from 'antd/lib/form'
import type { FormInstance } from 'antd/lib/form/hooks/useForm.d'
import { canGloballyManagePlugins, canInstallPlugins } from './access'
import { teamLogic } from '../teamLogic'
import { createDefaultPluginSource } from 'scenes/plugins/source/createDefaultPluginSource'

View File

@ -1,5 +1,5 @@
import { PluginConfigSchema } from '@posthog/plugin-scaffold'
import { FormInstance } from 'antd'
import type { FormInstance } from 'antd/lib/form/hooks/useForm.d'
import { PluginTypeWithConfig } from 'scenes/plugins/types'
// Keep this in sync with: posthog/api/plugin.py

View File

@ -1,4 +1,4 @@
import { kea } from 'kea'
import { BuiltLogic, kea } from 'kea'
import { router } from 'kea-router'
import posthog from 'posthog-js'
import type { sceneLogicType } from './sceneLogicType'
@ -38,6 +38,7 @@ export const sceneLogic = kea<sceneLogicType>({
connect: () => ({
logic: [router, userLogic, preflightLogic],
values: [featureFlagLogic, ['featureFlags']],
actions: [router, ['locationChanged']],
}),
path: ['scenes', 'sceneLogic'],
actions: {
@ -145,7 +146,7 @@ export const sceneLogic = kea<sceneLogicType>({
],
activeSceneLogic: [
(s) => [s.activeLoadedScene, s.sceneParams],
(activeLoadedScene, sceneParams) =>
(activeLoadedScene, sceneParams): BuiltLogic | null =>
activeLoadedScene?.logic
? activeLoadedScene.logic.build(activeLoadedScene.paramsToProps?.(sceneParams) || {})
: null,
@ -376,7 +377,7 @@ export const sceneLogic = kea<sceneLogicType>({
reloadBrowserDueToImportError: () => {
window.location.reload()
},
[router.actionTypes.locationChanged]: () => {
locationChanged: () => {
// Remove trailing slash
const {
location: { pathname, search, hash },

View File

@ -1,4 +1,4 @@
import { MutableRefObject as ReactMutableRefObject } from 'react'
import { MutableRefObject } from 'react'
import { kea } from 'kea'
import type { seekbarLogicType } from './seekbarLogicType'
import { sessionRecordingPlayerLogic } from 'scenes/session-recordings/player/sessionRecordingPlayerLogic'
@ -36,8 +36,8 @@ export const seekbarLogic = kea<seekbarLogicType>({
handleDown: (event: ReactInteractEvent) => ({ event }),
handleClick: (event: ReactInteractEvent) => ({ event }),
handleTickClick: (playerPosition: PlayerPosition) => ({ playerPosition }),
setSlider: (ref: ReactMutableRefObject<HTMLDivElement | null>) => ({ ref }),
setThumb: (ref: ReactMutableRefObject<HTMLDivElement | null>) => ({ ref }),
setSlider: (ref: MutableRefObject<HTMLDivElement | null>) => ({ ref }),
setThumb: (ref: MutableRefObject<HTMLDivElement | null>) => ({ ref }),
debouncedSetTime: (time: number) => ({ time }),
endSeeking: true,
},

View File

@ -37,8 +37,7 @@
"build:esbuild": "node frontend/build.mjs",
"prettier": "prettier --write \"./**/*.{js,mjs,ts,tsx,json,yaml,yml,css,scss}\"",
"prettier:check": "prettier --check \"./**/*.{js,mjs,ts,tsx,json,yaml,yml,css,scss}\"",
"typescript:check": "tsc",
"typescript:clean": "tsc --build --clean",
"typescript:check": "tsc --noEmit && echo \"No errors reported by tsc.\"",
"eslint": "eslint frontend/src",
"typegen:write": "kea-typegen write",
"typegen:check": "kea-typegen check",