Repository navigation
Partials accept functions #17003
Description
Activity
- changed the title
[-]Bug: Partials accept functions[/-][+]Partials accept functions[/+]on Jul 7, 2017 Addressed in TypeScript FAQs.
Apologies but it's not clear to me why a function is assignable to a partial interface based on that.
My issue is not to do with the parameters on the function, but that a function is assignable to a partial interface
Ah, I see the challenge...
From a type perspective, functions are a type of object, which can have properties. You are assigning a function to an object with no required properties. Therefore, a function with no properties is assignable to an interface with all optional properties.
Why all the cases you have in your playground example was because TypeScript did not detect weak types properly, and as of 2.4 it does. That means that strings and numbers are no longer assignable but these weak types.
I tried to use
object & Partial<T>as a type to avoid functions being assignable, but I am afraid functions are still considered subtypes of objects by the type system. But I might be missing something...Edit: Upon trying the below unfortunately it does not work due to an issue with unions
interface SinglePropA { a: 'test-a' } interface SinglePropB { b: 'test-b' } type SubsetAnimal = | SinglePropA | SinglePropB const testAandB: SubsetAnimal = { a: 'test-a', b: 'test-bs' } // passes on 2.4.1 and 2.5.0-dev.20170629
So after sleeping on it, I think I can restructure my use of Partial to achieve what I want with the following.
type ValueOne = { valueOne: 'value-one' } type ValueTwo = { valueTwo: 'value-two' } type SingleValue = | ValueOne | ValueTwo type MultiValue = & Partial< & ValueOne & ValueTwo > & SingleValue type Value = SingleValue | MultiValue type Method = () => Value type Argument = Method | Value type Library = (argument: Argument) => void const library: Library = (props) => {} library({ }) library(() => ({ }))
Cheers for looking into it
- addedQuestionAn issue which isn't directly actionable in codeAn issue which isn't directly actionable in code
on Jul 9, 2017 Adding an index signature to the interface you pass to the
Partialprevents it accepting functions.interface Foo { cat: string bar: number [key: string]: string | number | undefined } type Bar<Baz> = | Partial<Baz> | ( () => Partial<Baz> ) const notBar: Bar<Foo> = () => { } // fails on 2.4.1 and 2.5.0-dev.20170629 const alsoNotBar: Bar<Foo> = 'test' // fails on 2.4.1 const alsoAlsoNotBar: Bar<Foo> = false // fails on 2.4.1
edit: note, this does kill autocomplete though :/
just updating for anyone who comes across this via google.
on 2.4.1 the following works and retains autocomplete.
interface StylesComplete { propA: 'letter a' | 'a', propB: 'letter b' | 'b', } // A Partial on an interface will normally accept arbitrary functions // due to partials accepting empty objects which validate to anything in // typescript const doesNotFail: Partial<StylesComplete> = () => { } interface StylesLossy { [key: string]: string | undefined } type Styles = & StylesComplete & StylesLossy // intersection of // * an interface containing random props // * index signature interface // allows you to do a partial which will successfully fail on arbitrary // functions. // successfully fails const doesFail: Partial<Styles> = () => { }- locked and limited conversation to collaborators
on Jun 14, 2018
TypeScript Version: 2.4.0 / nightly (2.5.0-dev.201xxxxx)
2.4.1 and 2.5.0-dev.20170629 and 2.5.0-dev.20170707
Code
Expected behavior:
Partials should not accept functions
Actual behavior:
Partials accept functions
typescript-playground-example
Related Issues:
13132 has been marked as a duplicate of 7485 which has been closed
7485 is meant was meant to be closed by 16047 which has merged.
Edit: updated after testing on latest nightly and simplified example code