fix: use more reasonable type inference (#1963)

Use 'hasOwn' instead of 'hasOwnProperty' to complete more reasonable type inference and avoid possible bugs in the prototype chain.
This commit is contained in:
Zong 2021-05-09 10:46:11 +08:00 committed by GitHub
parent 42ed6abbdf
commit f3b9ebf571
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 33 additions and 24 deletions

View File

@ -1,3 +1,5 @@
import { hasOwn } from '@vue/shared'
const hsv2hsl = function(hue: number, sat: number, val: number) {
return [
hue,
@ -169,7 +171,7 @@ export default class Color {
options = options || {} as Options
for (const option in options) {
if (options.hasOwnProperty(option)) {
if (hasOwn(options, option)) {
this[option] = options[option]
}
}
@ -180,7 +182,7 @@ export default class Color {
set(prop: {[key: string]: any;} | any, value?: number) {
if (arguments.length === 1 && typeof prop === 'object') {
for (const p in prop) {
if (prop.hasOwnProperty(p)) {
if (hasOwn(prop, p)) {
this.set(p, prop[p])
}
}

View File

@ -1,4 +1,5 @@
import { nextTick } from 'vue'
import { hasOwn } from '@vue/shared'
import { createLoadingComponent } from './createLoadingComponent'
import type { ILoadingGlobalConfig, ILoadingInstance, ILoadingOptions } from './loading.type'
import { addClass, getStyle, removeClass } from '@element-plus/utils/dom'
@ -122,7 +123,7 @@ const Loading = function (options: ILoadingOptions = {}): ILoadingInstance {
// after instance render, then modify visible to trigger transition
nextTick().then(() => {
instance.visible.value = options.hasOwnProperty('visible') ? options.visible : true
instance.visible.value = hasOwn(options, 'visible') ? options.visible : true
})
if (options.fullscreen) {

View File

@ -1,4 +1,5 @@
import { h, watch, render } from 'vue'
import { hasOwn } from '@vue/shared'
import MessageBoxConstructor from './index.vue'
import isServer from '@element-plus/utils/isServer'
import { isVNode, isString } from '@element-plus/utils/util'
@ -85,8 +86,8 @@ const showMessage = (options: any) => {
} & MessageBoxState>
for (const prop in options) {
if (options.hasOwnProperty(prop) && !vm.$props.hasOwnProperty(prop)) {
vm[prop] = options[prop]
if (hasOwn(options, prop) && !hasOwn(vm.$props, prop)) {
vm[prop as string] = options[prop]
}
}

View File

@ -1,4 +1,5 @@
import { ref, getCurrentInstance, unref, watch } from 'vue'
import { hasOwn } from '@vue/shared'
import {
getKeysMap,
getRowIdentity,
@ -149,7 +150,7 @@ function useWatcher () {
const selectedMap = getKeysMap(selection.value, rowKey.value)
const dataMap = getKeysMap(data.value, rowKey.value)
for (const key in selectedMap) {
if (selectedMap.hasOwnProperty(key) && !dataMap[key]) {
if (hasOwn(selectedMap, key) && !dataMap[key]) {
deleted.push(selectedMap[key].row)
}
}

View File

@ -1,4 +1,5 @@
import { watch, getCurrentInstance, ComputedRef } from 'vue'
import { hasOwn } from '@vue/shared'
import { TableColumnCtx, TableColumn } from '../table.type'
function useWatcher(owner: ComputedRef<any>, props_: TableColumnCtx) {
@ -16,7 +17,7 @@ function useWatcher(owner: ComputedRef<any>, props_: TableColumnCtx) {
Object.keys(allAliases).forEach(key => {
const columnKey = aliases[key]
if (props_.hasOwnProperty(columnKey)) {
if (hasOwn(props_, columnKey)) {
watch(
() => props_[columnKey],
newVal => {
@ -54,7 +55,7 @@ function useWatcher(owner: ComputedRef<any>, props_: TableColumnCtx) {
}, aliases)
Object.keys(allAliases).forEach(key => {
const columnKey = aliases[key]
if (props_.hasOwnProperty(columnKey)) {
if (hasOwn(props_, columnKey)) {
watch(
() => props_[columnKey],
newVal => {

View File

@ -1,4 +1,5 @@
import { nextTick, ref, isRef, Ref } from 'vue'
import { hasOwn } from '@vue/shared'
import scrollbarWidth from '@element-plus/utils/scrollbar-width'
import isServer from '@element-plus/utils/isServer'
import { parseHeight } from './util'
@ -54,11 +55,11 @@ class TableLayout {
this.fixedBodyHeight = ref(null)
this.gutterWidth = scrollbarWidth()
for (const name in options) {
if (options.hasOwnProperty(name)) {
if (hasOwn(options, name)) {
if (isRef(this[name])) {
this[name].value = options[name]
this[name as string].value = options[name]
} else {
this[name] = options[name]
this[name as string] = options[name]
}
}
}

View File

@ -1,3 +1,4 @@
import { hasOwn } from '@vue/shared'
import { PopperInstance, IPopperOptions } from '@element-plus/popper'
import { getValueByPath } from '@element-plus/utils/util'
import { off, on } from '@element-plus/utils/dom'
@ -164,10 +165,6 @@ export const getKeysMap = function(
return arrayMap
}
function hasOwn(obj: AnyObject, key: string): boolean {
return Object.prototype.hasOwnProperty.call(obj, key)
}
export function mergeOptions<T, K>(defaults: T, config: K): T & K {
const options = {} as T & K
let key
@ -175,7 +172,7 @@ export function mergeOptions<T, K>(defaults: T, config: K): T & K {
options[key] = defaults[key]
}
for (key in config) {
if (hasOwn(config, key)) {
if (hasOwn(config as unknown as Indexable<any>, key)) {
const value = config[key]
if (typeof value !== 'undefined') {
options[key] = value

View File

@ -1,4 +1,5 @@
import { reactive } from 'vue'
import { hasOwn } from '@vue/shared'
import { markNodeData, NODE_KEY } from './util'
import TreeStore from './tree-store'
@ -104,7 +105,7 @@ export default class Node {
this.canFocus = false
for (const name in options) {
if (options.hasOwnProperty(name)) {
if (hasOwn(options, name)) {
this[name] = options[name]
}
}

View File

@ -1,3 +1,4 @@
import { hasOwn } from '@vue/shared'
import Node from './node'
import { getNodeKey } from './util'
import {
@ -35,7 +36,7 @@ export default class TreeStore {
this.currentNodeKey = null
for (const option in options) {
if (options.hasOwnProperty(option)) {
if (hasOwn(options, option)) {
this[option] = options[option]
}
}
@ -237,7 +238,7 @@ export default class TreeStore {
const allNodes: Node[] = []
const nodesMap = this.nodesMap
for (const nodeKey in nodesMap) {
if (nodesMap.hasOwnProperty(nodeKey)) {
if (hasOwn(nodesMap, nodeKey)) {
allNodes.push(nodesMap[nodeKey])
}
}

View File

@ -1,3 +1,4 @@
import { hasOwn } from '@vue/shared'
import type {
ElUploadProgressEvent,
ElUploadRequestOptions,
@ -82,7 +83,7 @@ export default function upload(option: ElUploadRequestOptions) {
const headers = option.headers || {}
for (const item in headers) {
if (headers.hasOwnProperty(item) && headers[item] !== null) {
if (hasOwn(headers, item) && headers[item] !== null) {
xhr.setRequestHeader(item, headers[item])
}
}

View File

@ -27,7 +27,7 @@
<script lang="ts">
import { defineComponent, ref } from 'vue'
import { NOOP } from '@vue/shared'
import { NOOP, hasOwn } from '@vue/shared'
import ajax from './ajax'
import UploadDragger from './upload-dragger.vue'
@ -186,7 +186,7 @@ export default defineComponent({
})
}
for (const p in rawFile) {
if (rawFile.hasOwnProperty(p)) {
if (hasOwn(rawFile, p)) {
processedFile[p] = rawFile[p]
}
}

View File

@ -9,6 +9,7 @@ import {
resolveDynamicComponent,
h,
} from 'vue'
import { hasOwn } from '@vue/shared'
import memo from 'lodash/memoize'
import { isNumber, isString, $ } from '@element-plus/utils/util'
@ -327,7 +328,7 @@ const createGrid = ({
// we use row,column to construct the key for indexing the map.
const key = `${rowIndex},${columnIndex}`
if (itemStyleCache.hasOwnProperty(key)) {
if (hasOwn(itemStyleCache, key)) {
return itemStyleCache[key]
} else {
const [, left] = getColumnPosition(props, columnIndex, $(cache))

View File

@ -9,6 +9,7 @@ import {
resolveDynamicComponent,
h,
} from 'vue'
import { hasOwn } from '@vue/shared'
import memo from 'lodash/memoize'
import { isNumber, isString, $ } from '@element-plus/utils/util'
@ -262,7 +263,7 @@ const createList = ({
)
let style: CSSProperties
if (itemStyleCache.hasOwnProperty(idx)) {
if (hasOwn(itemStyleCache, String(idx))) {
style = itemStyleCache[idx]
} else {
const offset = getItemOffset(props, idx, $(dynamicSizeCache))